{
  "repo": "tidbcloud/auditservice",
  "binary": "api",
  "binary_path": "cmd/api/main.go",
  "dependencies": {
    "AuditApiLifecycle.Startup": {
      "infrastructure": {},
      "services": []
    },
    "AuditApiLifecycle.LoadRemoteConfig": {
      "infrastructure": {},
      "services": [
        {
          "name": "config-service-oneconfig",
          "target_interface": "oneconfig-account/config.yaml",
          "operation_type": "remote_config",
          "target_repo": "tidbcloud/config-service",
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "READ REMOTE CONFIG",
              "trigger": "Load dynamic config before DB and route initialization",
              "conditions": [
                "Always"
              ],
              "implementation": "configs.LoadRemoteConfig -> viper.AddRemoteProvider(...); viper.ReadRemoteConfig(); go watchViperConfig(ctx)"
            }
          ]
        }
      ]
    },
    "AuditApiLifecycle.InitializeDB": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "Only when DB_DSN environment variable is set"
          ],
          "operations": [
            {
              "operation": "OPEN DB HANDLE",
              "trigger": "Create the shared auditlog database handle used by query, export, and settings APIs",
              "conditions": [
                "os.Getenv(\"DB_DSN\") != \"\""
              ],
              "implementation": "entity.InitDB(cfg, false) -> gorm.Open(mysql.Open(dsn), &gorm.Config{})"
            }
          ]
        }
      },
      "services": []
    },
    "AuditApiLifecycle.InitializeAuditService": {
      "infrastructure": {},
      "services": [
        {
          "name": "account-svc",
          "target_interface": "gRPC AccountAPIService",
          "operation_type": "grpc_connect",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "CREATE CLIENT CONN",
              "trigger": "Initialize the account service client used later by permission checks and event enrichment",
              "conditions": [
                "Always"
              ],
              "implementation": "account.NewAccountSvc(ctx, cfg) -> tigrpc.NewClientConn(cfg.AccountSvcAddr, ...); account.NewAccountAPIServiceClient(conn)"
            }
          ]
        },
        {
          "name": "core-svc",
          "target_interface": "gRPC CoreService",
          "operation_type": "grpc_connect",
          "target_repo": "tidbcloud/core-svc",
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "CREATE CLIENT CONN",
              "trigger": "Initialize the cluster-management client used later for cluster enrichment",
              "conditions": [
                "Always"
              ],
              "implementation": "cluster_management.NewCMSvc(ctx, cfg) -> tigrpc.NewClientConn(cfg.CMSvcAddr, ...); core.NewCoreServiceClient(conn)"
            }
          ]
        },
        {
          "name": "acl-svc",
          "target_interface": "gRPC AccessService",
          "operation_type": "grpc_connect",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "Always"
          ],
          "operations": [
            {
              "operation": "CREATE CLIENT CONN",
              "trigger": "Initialize the ACL service client used later for API key audit event enrichment",
              "conditions": [
                "Always"
              ],
              "implementation": "acl.NewAclSvcIface(ctx, cfg) -> tigrpc.NewClientConn(cfg.ACLSvcAddr, ...); acl.NewAccessServiceClient(conn)"
            }
          ]
        }
      ]
    },
    "AuditApiLifecycle.StartHTTPServer": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /healthz": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /ping": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /api/v1/audit/event_types": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /api/v1/audit/{org_id}/settings": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The authenticated caller has owner or audit-admin role in the target org"
          ],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Load the current org audit-log setting after permission checks pass",
              "conditions": [
                "checkIfHavePermission(c) returned ok == true"
              ],
              "implementation": "auditSvc.QueryOrgSettings(ctx, uriParams.OrgID) -> auditDao.QueryOrgSettings -> SELECT ... FROM org_audit_log_settings"
            }
          ]
        }
      },
      "services": [
        {
          "name": "account-svc",
          "target_interface": "GetUserRoleInOrg",
          "operation_type": "grpc",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "URI org_id is valid and current user context exists"
          ],
          "operations": [
            {
              "operation": "GET USER ROLE IN ORG",
              "trigger": "Verify that the current user is org owner or audit admin before revealing settings",
              "conditions": [
                "c.ShouldBindUri(&uriParams) succeeded",
                "tigin.GetCurrentUser(c) succeeded"
              ],
              "implementation": "checkIfHavePermission -> accountSvc.GetUserRoleInOrg(ctx, user.Email, uriParams.OrgID)"
            }
          ]
        }
      ]
    },
    "HTTP PUT /api/v1/audit/{org_id}/settings": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The authenticated caller has owner or audit-admin role and payload.Status is on/off"
          ],
          "operations": [
            {
              "operation": "INSERT OR UPDATE",
              "trigger": "Persist the new org audit-log setting",
              "conditions": [
                "checkIfHavePermission(c) returned ok == true",
                "payload.Status is SettingsOn or SettingsOff"
              ],
              "implementation": "auditSvc.UpdateOrgSettings(ctx, uriParams.OrgID, payload.Status) -> auditDao.UpdateOrgSettings -> SELECT + SAVE org_audit_log_settings"
            }
          ]
        }
      },
      "services": [
        {
          "name": "account-svc",
          "target_interface": "GetUserRoleInOrg",
          "operation_type": "grpc",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "URI org_id is valid and current user context exists"
          ],
          "operations": [
            {
              "operation": "GET USER ROLE IN ORG",
              "trigger": "Verify that the current user is org owner or audit admin before updating settings",
              "conditions": [
                "c.ShouldBindUri(&uriParams) succeeded",
                "tigin.GetCurrentUser(c) succeeded"
              ],
              "implementation": "checkIfHavePermission -> accountSvc.GetUserRoleInOrg(ctx, user.Email, uriParams.OrgID)"
            }
          ]
        },
        {
          "name": "auditlog-sdk-eventbus",
          "target_interface": "Submit EventEnableConsoleAuditLog",
          "operation_type": "event_submit",
          "target_repo": "tidbcloud/tiinf",
          "conditions": [
            "payload.Status is SettingsOn or SettingsOff"
          ],
          "operations": [
            {
              "operation": "SUBMIT EVENT",
              "trigger": "Emit a console audit-log toggle event regardless of whether UpdateOrgSettings returned an error",
              "conditions": [
                "payload.Status is valid"
              ],
              "implementation": "auditlog.NewEvent(ctx, auditlog.EventEnableConsoleAuditLog).ParseGIN(c).SetDetails(...).SetResult(err == nil).SetOrgID(uriParams.OrgID).Submit()"
            }
          ]
        }
      ]
    },
    "HTTP GET /api/v1/audit/{org_id}/audit_logs": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The authenticated caller has owner or audit-admin role and query binding succeeds"
          ],
          "operations": [
            {
              "operation": "SELECT + COUNT",
              "trigger": "Query audit events with pagination and filters for the org",
              "conditions": [
                "checkIfHavePermission(c) returned ok == true",
                "c.ShouldBindQuery(&payload) succeeded"
              ],
              "implementation": "auditSvc.QueryEvents(ctx, payload) -> auditDao.QueryEvents -> COUNT + FIND entity.Event"
            }
          ]
        }
      },
      "services": [
        {
          "name": "account-svc",
          "target_interface": "GetUserRoleInOrg",
          "operation_type": "grpc",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "URI org_id is valid and current user context exists"
          ],
          "operations": [
            {
              "operation": "GET USER ROLE IN ORG",
              "trigger": "Verify that the current user is org owner or audit admin before exposing audit logs",
              "conditions": [
                "c.ShouldBindUri(&uriParams) succeeded",
                "tigin.GetCurrentUser(c) succeeded"
              ],
              "implementation": "checkIfHavePermission -> accountSvc.GetUserRoleInOrg(ctx, user.Email, uriParams.OrgID)"
            }
          ]
        }
      ]
    },
    "HTTP GET /api/v1/audit/{org_id}/audit_logs/export": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The authenticated caller has owner or audit-admin role and export format is json/csv"
          ],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Load the full matching event set before encoding it as JSON or CSV",
              "conditions": [
                "checkIfHavePermission(c) returned ok == true",
                "payload.Format is ExportFormatJSON or ExportFormatCSV"
              ],
              "implementation": "auditSvc.ExportEvents(ctx, payload) -> auditDao.QueryEvents(..., ignorePagination=true)"
            }
          ]
        }
      },
      "services": [
        {
          "name": "account-svc",
          "target_interface": "GetUserRoleInOrg",
          "operation_type": "grpc",
          "target_repo": "tidbcloud/account",
          "conditions": [
            "URI org_id is valid and current user context exists"
          ],
          "operations": [
            {
              "operation": "GET USER ROLE IN ORG",
              "trigger": "Verify that the current user is org owner or audit admin before exporting logs",
              "conditions": [
                "c.ShouldBindUri(&uriParams) succeeded",
                "tigin.GetCurrentUser(c) succeeded"
              ],
              "implementation": "checkIfHavePermission -> accountSvc.GetUserRoleInOrg(ctx, user.Email, uriParams.OrgID)"
            }
          ]
        }
      ]
    },
    "HTTP GET /api/v1/ops-audit/event_types": {
      "infrastructure": {},
      "services": []
    },
    "HTTP GET /api/v1/ops-audit/{org_id}/settings": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The request passes AuthnOpsAK middleware"
          ],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Load the current org audit-log setting for ops callers",
              "conditions": [
                "AuthnOpsAK middleware validated the request"
              ],
              "implementation": "auditSvc.QueryOrgSettings(ctx, uriParams.OrgID) -> auditDao.QueryOrgSettings -> SELECT ... FROM org_audit_log_settings"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP GET /api/v1/ops-audit/{org_id}/audit_logs": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The request passes AuthnOpsAK middleware and query binding succeeds"
          ],
          "operations": [
            {
              "operation": "SELECT + COUNT",
              "trigger": "Query audit events with pagination and filters for ops callers",
              "conditions": [
                "AuthnOpsAK middleware validated the request",
                "c.ShouldBindQuery(&payload) succeeded"
              ],
              "implementation": "auditSvc.QueryEvents(ctx, payload) -> auditDao.QueryEvents -> COUNT + FIND entity.Event"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP GET /api/v1/ops-audit/{org_id}/audit_logs/export": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "The request passes AuthnOpsAK middleware and export format is json/csv"
          ],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Load the full matching event set before encoding it as JSON or CSV for ops callers",
              "conditions": [
                "AuthnOpsAK middleware validated the request",
                "payload.Format is ExportFormatJSON or ExportFormatCSV"
              ],
              "implementation": "auditSvc.ExportEvents(ctx, payload) -> auditDao.QueryEvents(..., ignorePagination=true)"
            }
          ]
        }
      },
      "services": []
    },
    "HTTP GET /v1beta1/auditLogs": {
      "infrastructure": {
        "mysql": {
          "conditions": [
            "OpenAPI auth and permission middlewares succeeded and query parameters are valid"
          ],
          "operations": [
            {
              "operation": "SELECT + COUNT",
              "trigger": "Query audit events using OpenAPI pageToken/pageSize semantics",
              "conditions": [
                "c.ShouldBindQuery(&req) succeeded",
                "time/pageToken validation succeeded",
                "getOrgIdFromAuthInfo(c) succeeded"
              ],
              "implementation": "auditSvc.QueryEvents(ctx, payload) -> auditDao.QueryEvents(filter.OpenApiQuery=true, filter.AscOrder=true)"
            }
          ]
        }
      },
      "services": [
        {
          "name": "account-openapi-auth",
          "target_interface": "identity + permission interceptors",
          "operation_type": "middleware_auth",
          "target_repo": "tidbcloud/tiinf",
          "conditions": [
            "Always for this route"
          ],
          "operations": [
            {
              "operation": "AUTHENTICATE AND AUTHORIZE",
              "trigger": "Resolve API key identity and verify permission before the handler runs",
              "conditions": [
                "Always"
              ],
              "implementation": "RegisterOpenApiRouter -> auth.GinGetIdentityInfoInterceptor(...); auth.GinPermissionCheckInterceptor(...)"
            }
          ]
        }
      ]
    }
  },
  "notes": [
    "The ops-audit routes use purely local AK/SK HMAC validation from AuthnOpsAK; unlike user routes they do not call account-svc for org-role checks.",
    "The v1beta1 route depends on auth middleware configured at registration time. The handler itself only runs after identity and permission checks succeed."
  ]
}
