- New page: /iam-users/:id/policies shows all policies in one view
- Separated into global policies and per-project policies sections
- Each section has inline add/remove with disabled duplicates
- Backend: new policies/overview/ endpoint returns global + project policies
- Replaces old popup-based policy management
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename "权限策略" to "全局权限策略" in dropdown menu
- Add info banner explaining global vs project-level in both dialogs
- Disable already-attached policies in global dropdown (grey out)
- Show policy type as tag (系统/自定义) in global policies table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add volc_login_allowed field to IAMUser model
- Add toggle-volc-login API endpoint
- Add toggle button in IAMUserList dropdown menu
- Sync status on user creation and toggle
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Detect InvalidPassword error and return user-friendly message
- Rollback user creation if password policy fails
- Add password requirements hint in create form
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add edit profile (display name, phone, email) with Volcengine sync
- Add IAMService.update_user for Volcengine UpdateUser API
- Add edit-profile API endpoint and URL
- Add Edit Profile dialog in IAMUserList frontend
- Verify admin change password, sub-account change password, set login password all working
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Admin: set sub-account AirGate login password via dropdown menu
- Admin: toggle sub-account login enabled/disabled
- Sub-account: change own password (sidebar "修改密码")
- Sub-account: auto-redirect to login page after password change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Login page: toggle between admin/sub-account login
- Auth store: isAdmin/isIamUser computed properties
- MainLayout: role-based sidebar (admin sees all, sub-account sees only my keys)
- HomeRedirect: auto-redirect based on role
- MyKeysView: sub-account can view/reveal their own API Keys
- Portal is completely isolated from admin functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New ArkApiKey model (encrypted storage, bound to user+project)
- Admin enters API Key from Volcengine console into AirGate
- Sub-accounts can only view their own keys
- Reveal endpoint decrypts key on demand with audit log
- Updated research report: documented Ark API limitation (CreateApiKey
doesn't return plaintext) and manual entry solution
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New VolcengineClient.call_json() for POST+JSON signing (Ark API)
- ArkService for API Key CRUD operations
- Backend views: list/create/toggle/delete ark keys per project
- Frontend: ArkKeysView with project selector, key table, create dialog
- Created key value shown once with copy button
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add "授权" button on each linked project row
- New dialog to select/deselect policies per project
- Backend does incremental diff: only attach new, detach removed
- Handle PolicyAttachConflict gracefully
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change password: current user can change their own password
- Admin management: superuser can create/toggle/reset-password for admins
- Operation log: view all system operations with type filter
- All operations are recorded to AlertRecord for audit trail
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Disable now removes all policies (saved to DB) + Enable restores them
- Project add: policies are now user-selected (checkbox), not auto-attached
- Fix serializer allow_blank for optional fields (email/phone/password)
- Better error reporting for policy detach/attach failures
- Handle duplicate user creation with clear error message
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- All dialogs use width="90%" + max-width for responsive layout
- Clarify "控制台密码" → "火山控制台密码" with explanation hint
(not AirGate login, but Volcengine console login for the sub-account)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Project-level authorization:
- Adding a project to a sub-account now auto-calls AttachPolicyInProject
to grant default policies (ArkFullAccess, TOSFullAccess) in that project scope
- Removing a project auto-calls DetachPolicyInProject to revoke those policies
- Each project records which policies were attached (attached_policies field)
so removal knows exactly what to revoke
Configuration:
- GlobalConfig.default_project_policies: configurable list of policies to
auto-attach (editable in Settings page, defaults to ArkFullAccess + TOSFullAccess)
IAM Service:
- Added attach_policy_in_project() and detach_policy_in_project() methods
using standard AttachUserPolicy/DetachUserPolicy with ProjectName parameter
Frontend:
- Projects dialog now shows "已授权策略" column with policy tags
- Settings page has "项目默认授权策略" config field
Alert logging:
- Project add/remove operations are logged with attached/detached policy details
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Data model:
- Add IAMUserProject model (sub-account → N projects, each with monitoring toggle)
- Remove old single project_name from IAMUser model
- Update SpendingRecord with per-project granularity
Backend:
- Project CRUD views: list/add/update-toggle/delete/toggle-all
- Create user view auto-adds first project if specified
- Scheduler aggregates spending across all enabled projects per user
- Per-project spending recorded in SpendingRecord + IAMUserProject.current_spending
- Alert details include per-project spending breakdown
Frontend:
- New "项目管理" dialog: add projects from Volcengine dropdown, toggle monitoring per project, remove projects, batch toggle all
- "项目" column in user table showing monitored/total count (clickable)
- BillingView: expandable rows showing per-project spending breakdown
- Create dialog: optional initial project selection
- Removed old single-project select from config dialog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace fixed-width table columns with min-width + table-layout="auto"
so tables stretch to fill available space instead of squeezing left
- Condense 6 action buttons into "划拨" + "更多" dropdown menu
- Add responsive grid columns for dashboard stats (xl:6 → xs:24)
- Unify page headers with .page-header CSS class
- Add global .el-table width:100% fix
- Consistent number formatting with toLocaleString()
- Clean up redundant style attributes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quota allocation system:
- Replace monthly budget with one-time quota allocation (prepaid model)
- Support both adding (+) and deducting (-) quota with underflow protection
- Stepped alerts at configurable percentages (e.g., 50%/80%/90%)
- Auto-disable when quota exhausted (100%), alert state resets on new allocation
- Quota allocation history with operator audit trail
IAM management:
- Create new IAM sub-accounts directly from AirGate (auto-generates API keys)
- SecretKey shown once in dialog with copy-to-clipboard
- Attach/detach IAM policies via UI (ArkFullAccess, TOSFullAccess, etc.)
- Sync existing users from Volcengine
- Project list pulled from Volcengine API for dropdown selection
Security & auth:
- API Key authentication for external systems (AirDrama integration)
- SECRET_KEY enforced in production (raises error if missing with DEBUG=False)
- APIKeyUser with proper pk/is_staff attributes for DRF compatibility
Infrastructure:
- Docker + docker-compose for backend and frontend
- Nginx reverse proxy for frontend with /api/ forwarding
- Entrypoint with auto-migrate and default admin creation
- SQLite data persisted via Docker volume at /app/data/
Bug fixes from audit:
- Fix frontend referencing non-existent fields (current_month_spending, effective_budget, budget_usage_percent)
- Fix scheduler using naive datetime.now() → timezone.now()
- Fix scheduler reading interval from settings instead of GlobalConfig DB
- Fix docker-compose SQLite volume mounting as directory
- Fix CORS origin with explicit port 80
- Remove dead config (VOLC_ACCESS_KEY/SK, MONITOR_INTERVAL from settings)
- Remove unused imports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend (Django 4.2 + DRF):
- Admin auth with SimpleJWT
- Volcengine API client with HMAC-SHA256 signing
- IAM user management (create/sync/import/disable/enable)
- Billing query with pagination
- Feishu webhook notifications (async)
- APScheduler for periodic spending checks
- AES-256 encrypted credential storage
- API key auth for external system integration
Frontend (Vue 3 + Element Plus):
- Login page
- Dashboard with stats overview
- IAM user list with per-user threshold config
- Billing view with spending progress bars
- Alert history with type filtering
- Settings page for global config and Volcengine account management
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>