Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
{
|
||||
"doc": "02-extension-points",
|
||||
"agent": "2/20",
|
||||
"generated_for": "admin-roles-support",
|
||||
"desired": {
|
||||
"legacy_limited_nav": [
|
||||
"dashboard.overview",
|
||||
"catalog.products",
|
||||
"feeds.list",
|
||||
"feeds.export_feeds",
|
||||
"catalog.categories",
|
||||
"catalog.attributes",
|
||||
"catalog.standard_fields",
|
||||
"billing.overview",
|
||||
"settings.profile"
|
||||
],
|
||||
"legacy_explicitly_off_examples": [
|
||||
"processing.monitor",
|
||||
"stores.hub",
|
||||
"marketing.campaigns",
|
||||
"marketing.brand_kit",
|
||||
"marketing.seo",
|
||||
"marketing.content_calendar",
|
||||
"marketing.reviews"
|
||||
],
|
||||
"staff_roles": ["admin", "developer", "support_staff"],
|
||||
"staff_access": {
|
||||
"admin": "full /admin and /api/admin",
|
||||
"developer": "full /admin and /api/admin (align with admin; keep prod-blocked dev-password/impersonate as env gate)",
|
||||
"support_staff": "support ticket queue/reply/assign only; no billing/plan/settings mutation"
|
||||
}
|
||||
},
|
||||
"current_role_model": {
|
||||
"platform": {
|
||||
"mechanism": "boolean users.is_platform_admin",
|
||||
"symbols": [
|
||||
{
|
||||
"name": "IsPlatformAdmin",
|
||||
"kind": "method",
|
||||
"path": "apps/api/internal/auth/invites.go",
|
||||
"line": 209,
|
||||
"sym": "sym:descrybe-v2:apps/api/internal/auth/invites.go:209:IsPlatformAdmin"
|
||||
},
|
||||
{
|
||||
"name": "RequirePlatformAdmin",
|
||||
"kind": "method",
|
||||
"path": "apps/api/internal/httpapi/middleware.go",
|
||||
"line": 245,
|
||||
"sym": "sym:descrybe-v2:apps/api/internal/httpapi/middleware.go:245:RequirePlatformAdmin"
|
||||
},
|
||||
{
|
||||
"name": "checkPlatformAdmin",
|
||||
"kind": "method",
|
||||
"path": "apps/api/internal/httpapi/middleware.go",
|
||||
"line": 262,
|
||||
"sym": "sym:descrybe-v2:apps/api/internal/httpapi/middleware.go:262:checkPlatformAdmin"
|
||||
},
|
||||
{
|
||||
"name": "requirePlatformAdmin",
|
||||
"kind": "function",
|
||||
"path": "apps/web/src/lib/admin-gate.ts",
|
||||
"line": 8,
|
||||
"sym": "sym:descrybe-v2:apps/web/src/lib/admin-gate.ts:8:requirePlatformAdmin"
|
||||
},
|
||||
{
|
||||
"name": "applyPlatformAdmins",
|
||||
"kind": "function",
|
||||
"path": "apps/api/cmd/migrator/admins.go",
|
||||
"line": 13,
|
||||
"sym": "sym:descrybe-v2:apps/api/cmd/migrator/admins.go:13:applyPlatformAdmins"
|
||||
}
|
||||
],
|
||||
"missing": ["staff_role enum", "support_staff", "developer role", "assign-staff APIs"]
|
||||
},
|
||||
"company_membership": {
|
||||
"roles": ["admin", "member"],
|
||||
"api_key_role": "api",
|
||||
"symbols": [
|
||||
{
|
||||
"name": "CompanyAdminAllowed",
|
||||
"path": "apps/api/internal/httpapi/middleware.go",
|
||||
"line": 43
|
||||
},
|
||||
{
|
||||
"name": "allowCompanyAdminOrPlatform",
|
||||
"path": "apps/api/internal/httpapi/middleware.go",
|
||||
"line": 58
|
||||
}
|
||||
]
|
||||
},
|
||||
"support_message_author_roles": ["user", "agent", "system"],
|
||||
"note": "author_role=agent is message authorship, not users.staff_role"
|
||||
},
|
||||
"admin_web_routes": {
|
||||
"nav_component": {
|
||||
"name": "AdminNav",
|
||||
"path": "apps/web/src/lib/components/AdminNav.svelte",
|
||||
"line": 30,
|
||||
"menu_items": [
|
||||
"/admin",
|
||||
"/admin/users",
|
||||
"/admin/analytics",
|
||||
"/admin/billing",
|
||||
"/admin/support",
|
||||
"/admin/stuck-products",
|
||||
"/admin/settings"
|
||||
]
|
||||
},
|
||||
"layout_gate": {
|
||||
"path": "apps/web/src/routes/+layout.svelte",
|
||||
"showAdminNav": "me.user.is_platform_admin"
|
||||
},
|
||||
"pages": [
|
||||
{ "href": "/admin", "file": "apps/web/src/routes/admin/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/users", "file": "apps/web/src/routes/admin/users/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/analytics", "file": "apps/web/src/routes/admin/analytics/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/billing", "file": "apps/web/src/routes/admin/billing/+page.svelte", "in_nav": true, "hosts": "PlanPermissionsPanel" },
|
||||
{ "href": "/admin/support", "file": "apps/web/src/routes/admin/support/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/support/[id]", "file": "apps/web/src/routes/admin/support/[id]/+page.svelte", "in_nav": false },
|
||||
{ "href": "/admin/stuck-products", "file": "apps/web/src/routes/admin/stuck-products/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/settings", "file": "apps/web/src/routes/admin/settings/+page.svelte", "in_nav": true },
|
||||
{ "href": "/admin/tasks-cleanup", "file": "apps/web/src/routes/admin/tasks-cleanup/+page.svelte", "in_nav": false },
|
||||
{ "href": "/admin/logs", "file": "apps/web/src/routes/admin/logs/+page.svelte", "in_nav": false },
|
||||
{ "href": "/admin/bootstrap", "file": "apps/web/src/routes/admin/bootstrap/+page.svelte", "in_nav": false },
|
||||
{ "href": "/admin/migrate-organizations", "file": "apps/web/src/routes/admin/migrate-organizations/+page.svelte", "in_nav": false }
|
||||
]
|
||||
},
|
||||
"admin_api": {
|
||||
"mount": {
|
||||
"path": "apps/api/internal/httpapi/server.go",
|
||||
"line": 294,
|
||||
"middleware": ["RequireSession", "RequirePlatformAdmin"],
|
||||
"prefix": "/api/admin"
|
||||
},
|
||||
"routes": [
|
||||
"GET /users",
|
||||
"POST /users/{id}/dev-password",
|
||||
"POST /users/{id}/impersonate",
|
||||
"GET /companies",
|
||||
"GET /readiness",
|
||||
"GET /analytics",
|
||||
"GET /jobs",
|
||||
"POST /jobs/stuck-cleanup",
|
||||
"GET|PUT /settings",
|
||||
"POST /settings/mail/test",
|
||||
"GET|POST /plans",
|
||||
"GET|PUT /plans/{planID}/features",
|
||||
"POST /plans/{planID}/features/enable-all",
|
||||
"POST /plans/{planID}/features/disable-all",
|
||||
"GET|PUT /feature-gates",
|
||||
"PUT /feature-gates/sections/{section}",
|
||||
"POST /plans/assign",
|
||||
"POST /credits",
|
||||
"POST /billing/run-cycles",
|
||||
"POST /emails/set-password",
|
||||
"GET /support/tickets",
|
||||
"GET /support/tickets/{id}",
|
||||
"POST /support/tickets/{id}/messages",
|
||||
"PATCH /support/tickets/{id}"
|
||||
],
|
||||
"dev_handlers": {
|
||||
"path": "apps/api/internal/httpapi/admin_dev_handlers.go",
|
||||
"production": "404 / blocked"
|
||||
}
|
||||
},
|
||||
"plan_permissions_panel": {
|
||||
"component": {
|
||||
"name": "PlanPermissionsPanel",
|
||||
"path": "apps/web/src/lib/components/admin/PlanPermissionsPanel.svelte",
|
||||
"line": 84
|
||||
},
|
||||
"client": {
|
||||
"path": "apps/web/src/lib/admin-plan-permissions.ts",
|
||||
"symbols": [
|
||||
"isPlanPermissionsApiUnavailable",
|
||||
"listAdminPlansWithFeatures",
|
||||
"loadFeatureGates",
|
||||
"saveFeatureGates",
|
||||
"enableAllPlanFeatures",
|
||||
"disableAllPlanFeatures"
|
||||
]
|
||||
},
|
||||
"catalog": "apps/web/src/lib/plan-feature-catalog.ts",
|
||||
"host": "apps/web/src/routes/admin/billing/+page.svelte",
|
||||
"prior_doc": "docs/plan-permissions/08-admin-ui.md"
|
||||
},
|
||||
"plans_is_custom_legacy_a1": {
|
||||
"symbols": [
|
||||
{
|
||||
"name": "IsPublicProductPlan",
|
||||
"path": "apps/api/internal/billing/service.go",
|
||||
"line": 485,
|
||||
"public_names": ["Free", "Starter", "Growth", "Business", "Enterprise"]
|
||||
},
|
||||
{
|
||||
"name": "IsCustomPackage",
|
||||
"path": "apps/api/internal/billing/custom_package_features.go",
|
||||
"line": 19,
|
||||
"rule": "isCustom || !IsPublicProductPlan(name)",
|
||||
"sym": "sym:descrybe-v2:apps/api/internal/billing/custom_package_features.go:19:IsCustomPackage"
|
||||
},
|
||||
{
|
||||
"name": "DefaultPlanFeatures",
|
||||
"path": "apps/api/internal/billing/plan_features.go",
|
||||
"line": 71,
|
||||
"custom_default": "all FeatureCatalogKeys true"
|
||||
},
|
||||
{
|
||||
"name": "prepareCustomPackageCreateFeatures",
|
||||
"path": "apps/api/internal/billing/custom_package_features.go",
|
||||
"line": 49
|
||||
}
|
||||
],
|
||||
"a1_as_test_fixture": {
|
||||
"tests": "apps/api/internal/billing/custom_package_features_test.go",
|
||||
"behavior": "plan name A1 ⇒ IsCustomPackage true ⇒ all features ON"
|
||||
},
|
||||
"company_a1": {
|
||||
"legacy_mysql_name": "A1 Slovenija",
|
||||
"legacy_company_id": "97e1a309-3d23-4aa2-b518-8e8d7afdfec7",
|
||||
"postgres_company_id": "ee246275-dec0-4446-9e83-58d0c16c258a",
|
||||
"display_name_after_seed": "Local Demo Co",
|
||||
"seed_plan": "Enterprise",
|
||||
"seed_is_custom": true,
|
||||
"docs": ["docs/demo-user.md", "docs/migrate-from-descrybe-new.md"]
|
||||
},
|
||||
"is_legacy_flag": false,
|
||||
"legacy_feature_profile": false
|
||||
},
|
||||
"support": {
|
||||
"tenant": {
|
||||
"ui": [
|
||||
"apps/web/src/routes/support/+page.svelte",
|
||||
"apps/web/src/routes/support/new/+page.svelte",
|
||||
"apps/web/src/routes/support/[ticketId]/+page.svelte"
|
||||
],
|
||||
"api_prefix": "/api/support",
|
||||
"handlers_file": "apps/api/internal/httpapi/support_handlers.go",
|
||||
"auth": "RequireSession + RequireCompany"
|
||||
},
|
||||
"admin": {
|
||||
"ui": [
|
||||
"apps/web/src/routes/admin/support/+page.svelte",
|
||||
"apps/web/src/routes/admin/support/[id]/+page.svelte"
|
||||
],
|
||||
"client": "apps/web/src/lib/support/admin-api.ts",
|
||||
"api_prefix": "/api/admin/support",
|
||||
"auth": "RequirePlatformAdmin only",
|
||||
"service_symbols": [
|
||||
{
|
||||
"name": "ListAdmin",
|
||||
"path": "apps/api/internal/support/tickets.go",
|
||||
"line": 80
|
||||
},
|
||||
{
|
||||
"name": "GetAdmin",
|
||||
"path": "apps/api/internal/support/tickets.go",
|
||||
"line": 158
|
||||
},
|
||||
{
|
||||
"name": "ReplyAsAgent",
|
||||
"path": "apps/api/internal/support/tickets.go",
|
||||
"line": 325
|
||||
},
|
||||
{
|
||||
"name": "UpdateAdmin",
|
||||
"path": "apps/api/internal/support/tickets.go",
|
||||
"line": 428,
|
||||
"supports": ["status", "priority", "assignee_admin_user_id", "clear_assignee"]
|
||||
}
|
||||
],
|
||||
"schema": "apps/api/sql/schema/025_support_center.sql"
|
||||
},
|
||||
"csat_rating": false,
|
||||
"staff_inbox_filter": false
|
||||
},
|
||||
"tenant_nav_gating": {
|
||||
"component": "apps/web/src/lib/components/Nav.svelte",
|
||||
"mechanism": "planCapabilities.can(featureKey); adminOnly uses showAdmin",
|
||||
"processing_item": {
|
||||
"href": "/processing",
|
||||
"feature": "processing.monitor",
|
||||
"desired_for_legacy": "off"
|
||||
}
|
||||
},
|
||||
"extension_points": [
|
||||
{
|
||||
"id": "staff-rbac",
|
||||
"prefer": "extend RequirePlatformAdmin / checkPlatformAdmin",
|
||||
"add": "users.staff_role (admin|developer|support_staff) additive migration",
|
||||
"apis": "list/assign staff roles (admin-only)",
|
||||
"web": "filter AdminNav + requirePlatformAdmin → requireStaffCapability"
|
||||
},
|
||||
{
|
||||
"id": "legacy-feature-profile",
|
||||
"prefer": "extend DefaultPlanFeatures + seed/ApplyDefaultMatrix",
|
||||
"detect": ["plan name patterns (A1, …)", "optional plans.is_legacy", "company flag if needed"],
|
||||
"do_not_conflate": "is_custom / IsCustomPackage enable-all packaging",
|
||||
"ui": "PlanPermissionsPanel legacy badge + apply profile"
|
||||
},
|
||||
{
|
||||
"id": "support-staff-least-privilege",
|
||||
"prefer": "same /api/admin/support/* handlers with role-aware middleware",
|
||||
"optional": "ListAdmin filter by assignee; claim/unassign UX",
|
||||
"block_for_support_staff": ["/api/admin/plans*", "/api/admin/credits", "/api/admin/settings", "/api/admin/billing/*"]
|
||||
},
|
||||
{
|
||||
"id": "support-csat",
|
||||
"status": "absent",
|
||||
"hook": "after ticket resolved/closed — new columns + tenant UI"
|
||||
}
|
||||
],
|
||||
"gaps": [
|
||||
{
|
||||
"desired": "legacy limited nav",
|
||||
"current": "A1/custom/Enterprise resolve to all features ON",
|
||||
"severity": "high"
|
||||
},
|
||||
{
|
||||
"desired": "admin/developer full admin",
|
||||
"current": "single is_platform_admin boolean; no developer role",
|
||||
"severity": "high"
|
||||
},
|
||||
{
|
||||
"desired": "support_staff ticket access only",
|
||||
"current": "support admin requires full platform admin (same as billing)",
|
||||
"severity": "high"
|
||||
},
|
||||
{
|
||||
"desired": "staff assign from orgs UI",
|
||||
"current": "users list badge only; bootstrap cannot create admins",
|
||||
"severity": "medium"
|
||||
},
|
||||
{
|
||||
"desired": "CSAT / ratings",
|
||||
"current": "not in support package",
|
||||
"severity": "medium"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user