@endora-commerce/mod-admin-users 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/index.d.ts +47 -0
  4. package/dist/admin/index.d.ts.map +1 -0
  5. package/dist/admin/index.js +44 -0
  6. package/dist/admin/index.js.map +1 -0
  7. package/dist/admin/pages/AdminRolesPage.d.ts +3 -0
  8. package/dist/admin/pages/AdminRolesPage.d.ts.map +1 -0
  9. package/dist/admin/pages/AdminRolesPage.js +180 -0
  10. package/dist/admin/pages/AdminRolesPage.js.map +1 -0
  11. package/dist/admin/pages/AdminUsersPage.d.ts +3 -0
  12. package/dist/admin/pages/AdminUsersPage.d.ts.map +1 -0
  13. package/dist/admin/pages/AdminUsersPage.js +151 -0
  14. package/dist/admin/pages/AdminUsersPage.js.map +1 -0
  15. package/dist/admin/permission-label.d.ts +26 -0
  16. package/dist/admin/permission-label.d.ts.map +1 -0
  17. package/dist/admin/permission-label.js +67 -0
  18. package/dist/admin/permission-label.js.map +1 -0
  19. package/dist/backend/cli/create-admin.d.ts +16 -0
  20. package/dist/backend/cli/create-admin.d.ts.map +1 -0
  21. package/dist/backend/cli/create-admin.js +101 -0
  22. package/dist/backend/cli/create-admin.js.map +1 -0
  23. package/dist/backend/demo/reset.d.ts +15 -0
  24. package/dist/backend/demo/reset.d.ts.map +1 -0
  25. package/dist/backend/demo/reset.js +13 -0
  26. package/dist/backend/demo/reset.js.map +1 -0
  27. package/dist/backend/demo/rows.d.ts +50 -0
  28. package/dist/backend/demo/rows.d.ts.map +1 -0
  29. package/dist/backend/demo/rows.js +73 -0
  30. package/dist/backend/demo/rows.js.map +1 -0
  31. package/dist/backend/demo/seed.d.ts +24 -0
  32. package/dist/backend/demo/seed.d.ts.map +1 -0
  33. package/dist/backend/demo/seed.js +43 -0
  34. package/dist/backend/demo/seed.js.map +1 -0
  35. package/dist/backend/entities/admin-user.entity.d.ts +44 -0
  36. package/dist/backend/entities/admin-user.entity.d.ts.map +1 -0
  37. package/dist/backend/entities/admin-user.entity.js +115 -0
  38. package/dist/backend/entities/admin-user.entity.js.map +1 -0
  39. package/dist/backend/index.d.ts +77 -0
  40. package/dist/backend/index.d.ts.map +1 -0
  41. package/dist/backend/index.js +111 -0
  42. package/dist/backend/index.js.map +1 -0
  43. package/dist/backend/plugin.d.ts +70 -0
  44. package/dist/backend/plugin.d.ts.map +1 -0
  45. package/dist/backend/plugin.js +50 -0
  46. package/dist/backend/plugin.js.map +1 -0
  47. package/dist/backend/routes.admin.d.ts +32 -0
  48. package/dist/backend/routes.admin.d.ts.map +1 -0
  49. package/dist/backend/routes.admin.js +192 -0
  50. package/dist/backend/routes.admin.js.map +1 -0
  51. package/dist/backend/routes.impersonation.d.ts +25 -0
  52. package/dist/backend/routes.impersonation.d.ts.map +1 -0
  53. package/dist/backend/routes.impersonation.js +108 -0
  54. package/dist/backend/routes.impersonation.js.map +1 -0
  55. package/dist/backend/routes.public.d.ts +20 -0
  56. package/dist/backend/routes.public.d.ts.map +1 -0
  57. package/dist/backend/routes.public.js +75 -0
  58. package/dist/backend/routes.public.js.map +1 -0
  59. package/dist/backend/services/admin-auth-service.d.ts +47 -0
  60. package/dist/backend/services/admin-auth-service.d.ts.map +1 -0
  61. package/dist/backend/services/admin-auth-service.js +93 -0
  62. package/dist/backend/services/admin-auth-service.js.map +1 -0
  63. package/dist/backend/services/admin-user-ports.d.ts +75 -0
  64. package/dist/backend/services/admin-user-ports.d.ts.map +1 -0
  65. package/dist/backend/services/admin-user-ports.js +160 -0
  66. package/dist/backend/services/admin-user-ports.js.map +1 -0
  67. package/dist/backend/services/admin-user-service.d.ts +134 -0
  68. package/dist/backend/services/admin-user-service.d.ts.map +1 -0
  69. package/dist/backend/services/admin-user-service.js +241 -0
  70. package/dist/backend/services/admin-user-service.js.map +1 -0
  71. package/dist/backend/services/impersonation-service.d.ts +65 -0
  72. package/dist/backend/services/impersonation-service.d.ts.map +1 -0
  73. package/dist/backend/services/impersonation-service.js +103 -0
  74. package/dist/backend/services/impersonation-service.js.map +1 -0
  75. package/dist/backend/services/two-factor-enrolments.d.ts +19 -0
  76. package/dist/backend/services/two-factor-enrolments.d.ts.map +1 -0
  77. package/dist/backend/services/two-factor-enrolments.js +2 -0
  78. package/dist/backend/services/two-factor-enrolments.js.map +1 -0
  79. package/dist/manifest.d.ts +182 -0
  80. package/dist/manifest.d.ts.map +1 -0
  81. package/dist/manifest.js +208 -0
  82. package/dist/manifest.js.map +1 -0
  83. package/dist/migrations/20260425T053028_admin_users_init.d.ts +11 -0
  84. package/dist/migrations/20260425T053028_admin_users_init.d.ts.map +1 -0
  85. package/dist/migrations/20260425T053028_admin_users_init.js +51 -0
  86. package/dist/migrations/20260425T053028_admin_users_init.js.map +1 -0
  87. package/dist/migrations/20260819T155150_admin_users_fold_email_case.d.ts +55 -0
  88. package/dist/migrations/20260819T155150_admin_users_fold_email_case.d.ts.map +1 -0
  89. package/dist/migrations/20260819T155150_admin_users_fold_email_case.js +106 -0
  90. package/dist/migrations/20260819T155150_admin_users_fold_email_case.js.map +1 -0
  91. package/dist/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.d.ts +25 -0
  92. package/dist/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.d.ts.map +1 -0
  93. package/dist/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.js +29 -0
  94. package/dist/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.js.map +1 -0
  95. package/dist/migrations/index.d.ts +29 -0
  96. package/dist/migrations/index.d.ts.map +1 -0
  97. package/dist/migrations/index.js +33 -0
  98. package/dist/migrations/index.js.map +1 -0
  99. package/docs/admin_users.md +53 -0
  100. package/i18n/en.json +5 -0
  101. package/i18n/pl.json +5 -0
  102. package/package.json +100 -0
  103. package/tailwind.css +14 -0
@@ -0,0 +1,25 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * Drops `admin_users.two_factor_secret`, the superseded admin 2FA column.
4
+ *
5
+ * This half is further gone than the customer one: the column has **no writer
6
+ * anywhere in the tree** — an entity declaration and the init DDL, and nothing
7
+ * else. Admin 2FA is `mfa`'s, over `mfa_enrolments`, with an encrypted secret
8
+ * and single-use recovery-code rows; `mfa`'s own init migration records this
9
+ * column as SUPERSEDED.
10
+ *
11
+ * **Nothing is destroyed.** Measured on the dev database on 2026-08-25:
12
+ * `admin_users` holds 3 rows, of which `count(two_factor_secret)` is 0. There
13
+ * is no client deployment and no production database. `down()` re-creates the
14
+ * column's shape and nothing else, because there has never been a value to
15
+ * restore.
16
+ *
17
+ * `two_factor_confirmed_at` deliberately stays — see the sibling migration in
18
+ * `customer_accounts` and
19
+ * `specs/087-tenant-scope-enforcement/superseded-2fa-analysis.md` §7.
20
+ */
21
+ export declare class Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret extends Migration {
22
+ up(): Promise<void>;
23
+ down(): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=20260825T124801_admin_users_drop_legacy_two_factor_secret.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260825T124801_admin_users_drop_legacy_two_factor_secret.d.ts","sourceRoot":"","sources":["../../src/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,2DAA4D,SAAQ,SAAS;IACzE,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAInB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAGrC"}
@@ -0,0 +1,29 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * Drops `admin_users.two_factor_secret`, the superseded admin 2FA column.
4
+ *
5
+ * This half is further gone than the customer one: the column has **no writer
6
+ * anywhere in the tree** — an entity declaration and the init DDL, and nothing
7
+ * else. Admin 2FA is `mfa`'s, over `mfa_enrolments`, with an encrypted secret
8
+ * and single-use recovery-code rows; `mfa`'s own init migration records this
9
+ * column as SUPERSEDED.
10
+ *
11
+ * **Nothing is destroyed.** Measured on the dev database on 2026-08-25:
12
+ * `admin_users` holds 3 rows, of which `count(two_factor_secret)` is 0. There
13
+ * is no client deployment and no production database. `down()` re-creates the
14
+ * column's shape and nothing else, because there has never been a value to
15
+ * restore.
16
+ *
17
+ * `two_factor_confirmed_at` deliberately stays — see the sibling migration in
18
+ * `customer_accounts` and
19
+ * `specs/087-tenant-scope-enforcement/superseded-2fa-analysis.md` §7.
20
+ */
21
+ export class Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret extends Migration {
22
+ async up() {
23
+ this.addSql(`alter table "admin_users" drop column "two_factor_secret";`);
24
+ }
25
+ async down() {
26
+ this.addSql(`alter table "admin_users" add column "two_factor_secret" varchar(64) null;`);
27
+ }
28
+ }
29
+ //# sourceMappingURL=20260825T124801_admin_users_drop_legacy_two_factor_secret.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260825T124801_admin_users_drop_legacy_two_factor_secret.js","sourceRoot":"","sources":["../../src/migrations/20260825T124801_admin_users_drop_legacy_two_factor_secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,2DAA4D,SAAQ,SAAS;IAC/E,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,4DAA4D,CAAC,CAAC;IAC5E,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,4EAA4E,CAAC,CAAC;IAC5F,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The `./migrations` subpath — every migration class this module owns, as one
3
+ * ordered `migrations` array.
4
+ *
5
+ * The array is what the platform reads when this module is **installed**:
6
+ * `src/packages/package-runtime.ts` takes `exported['migrations']` and refuses
7
+ * the package outright when it is absent (D-168).
8
+ *
9
+ * Listed in ascending timestamp, which orders **this module's own** migrations
10
+ * and nothing else (feature 081). Where the block sits relative to every other
11
+ * module's is decided by the manifest `dependencies` graph.
12
+ *
13
+ * The **named** exports stay, and the asymmetry with `./backend` — which
14
+ * publishes an array and no entity class by name (D-168) — is deliberate.
15
+ * `db/migrations-registry.generated.ts` imports each class by name from this
16
+ * specifier, and a migration class name is contract in a way an entity class
17
+ * name is not: `mikro_orm_migrations` persists it, so it is a string every
18
+ * already-migrated database holds.
19
+ *
20
+ * A class that is in neither the array nor the barrel is a migration that does
21
+ * not run: `migration:pending` reports nothing pending and the first symptom
22
+ * is a query against a table nobody created.
23
+ */
24
+ import { Migration20260425T053028AdminUsersInit } from './20260425T053028_admin_users_init.js';
25
+ import { Migration20260819T155150AdminUsersFoldEmailCase } from './20260819T155150_admin_users_fold_email_case.js';
26
+ import { Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret } from './20260825T124801_admin_users_drop_legacy_two_factor_secret.js';
27
+ export declare const migrations: (typeof Migration20260425T053028AdminUsersInit)[];
28
+ export { Migration20260425T053028AdminUsersInit, Migration20260819T155150AdminUsersFoldEmailCase, Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret, };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sCAAsC,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,+CAA+C,EAAE,MAAM,kDAAkD,CAAC;AACnH,OAAO,EAAE,2DAA2D,EAAE,MAAM,gEAAgE,CAAC;AAE7I,eAAO,MAAM,UAAU,mDAItB,CAAC;AAEF,OAAO,EACL,sCAAsC,EACtC,+CAA+C,EAC/C,2DAA2D,GAC5D,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The `./migrations` subpath — every migration class this module owns, as one
3
+ * ordered `migrations` array.
4
+ *
5
+ * The array is what the platform reads when this module is **installed**:
6
+ * `src/packages/package-runtime.ts` takes `exported['migrations']` and refuses
7
+ * the package outright when it is absent (D-168).
8
+ *
9
+ * Listed in ascending timestamp, which orders **this module's own** migrations
10
+ * and nothing else (feature 081). Where the block sits relative to every other
11
+ * module's is decided by the manifest `dependencies` graph.
12
+ *
13
+ * The **named** exports stay, and the asymmetry with `./backend` — which
14
+ * publishes an array and no entity class by name (D-168) — is deliberate.
15
+ * `db/migrations-registry.generated.ts` imports each class by name from this
16
+ * specifier, and a migration class name is contract in a way an entity class
17
+ * name is not: `mikro_orm_migrations` persists it, so it is a string every
18
+ * already-migrated database holds.
19
+ *
20
+ * A class that is in neither the array nor the barrel is a migration that does
21
+ * not run: `migration:pending` reports nothing pending and the first symptom
22
+ * is a query against a table nobody created.
23
+ */
24
+ import { Migration20260425T053028AdminUsersInit } from './20260425T053028_admin_users_init.js';
25
+ import { Migration20260819T155150AdminUsersFoldEmailCase } from './20260819T155150_admin_users_fold_email_case.js';
26
+ import { Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret } from './20260825T124801_admin_users_drop_legacy_two_factor_secret.js';
27
+ export const migrations = [
28
+ Migration20260425T053028AdminUsersInit,
29
+ Migration20260819T155150AdminUsersFoldEmailCase,
30
+ Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret,
31
+ ];
32
+ export { Migration20260425T053028AdminUsersInit, Migration20260819T155150AdminUsersFoldEmailCase, Migration20260825T124801AdminUsersDropLegacyTwoFactorSecret, };
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sCAAsC,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,+CAA+C,EAAE,MAAM,kDAAkD,CAAC;AACnH,OAAO,EAAE,2DAA2D,EAAE,MAAM,gEAAgE,CAAC;AAE7I,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,sCAAsC;IACtC,+CAA+C;IAC/C,2DAA2D;CAC5D,CAAC;AAEF,OAAO,EACL,sCAAsC,EACtC,+CAA+C,EAC/C,2DAA2D,GAC5D,CAAC"}
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: admin_users
3
+ description: Platform Administrator accounts + impersonation
4
+ ---
5
+
6
+ # `admin_users`
7
+
8
+ Platform Administrator accounts (separate from Customer Accounts), plus
9
+ the impersonation flow.
10
+
11
+ ## Public surface
12
+
13
+ User + role CRUD is gated by the `admin_users:manage` permission.
14
+
15
+ | Verb + Path | Purpose |
16
+ | --- | --- |
17
+ | `POST /api/v1/auth/admin/login` | Admin login (2FA challenge if Role requires it) |
18
+ | `POST /api/v1/auth/admin/logout` | Destroy admin session |
19
+ | `GET /api/v1/admin/admin-users` | List admin users (deleted rows filtered) |
20
+ | `POST /api/v1/admin/admin-users` | Create admin user; rejects dup email with `EMAIL_ALREADY_REGISTERED` |
21
+ | `PATCH /api/v1/admin/admin-users/:id` | Update name / role assignment / status |
22
+ | `DELETE /api/v1/admin/admin-users/:id` | Soft delete (sets `deletedAt` + `status='inactive'`) |
23
+ | `GET /api/v1/admin/admin-roles` | List roles with their permission arrays |
24
+ | `PUT /api/v1/admin/admin-roles/:code` | Upsert role by code; unknown permissions return 400 `VALIDATION_FAILED` |
25
+ | `DELETE /api/v1/admin/admin-roles/:id` | Delete; refuses with 409 `ADMIN_ROLE_IN_USE` if any user is still assigned — **including a soft-deleted one**, whose assignment comes back when the account is restored. The refusal names which population holds the role (`details.code` is `assigned` or `assigned_to_deleted`) and how many there are |
26
+ | `GET /api/v1/admin/permissions` | Canonical permission catalogue (module / code / label) used by the matrix UI |
27
+ | `POST /api/v1/admin/organizations/:id/impersonate` | Begin impersonation; writes `impersonation.start` audit row before issuing the cookie |
28
+ | `POST /api/v1/admin/impersonation/end` | Restore the original admin session |
29
+
30
+ ## Impersonation model
31
+
32
+ `impersonation-service.ts` implements the switch-user pattern: starts a
33
+ new session keyed to the target Customer + admin shadow id; ends cleanly,
34
+ writing `impersonation.end`. Every action taken during an impersonated
35
+ session carries both `actorAdminUserId` and `impersonatedCustomerAccountId`
36
+ through the audit log.
37
+
38
+ ## Entities
39
+
40
+ `AdminUser` (email, passwordHash, two-factor state, single `adminRoleId`,
41
+ `status`, soft-delete `deletedAt`).
42
+
43
+ `AdminRole` (code, display name, JSONB `permissions[]`,
44
+ `requiresTwoFactor`). The wildcard `*` is bootstrap-only and rejected by
45
+ the upsert route.
46
+
47
+ ## Extension points
48
+
49
+ - **Custom login challenges** — slot before the password verify in
50
+ `admin-auth-service.ts`.
51
+ - **Impersonation audit consumers** — every audit row with action
52
+ `impersonation.start|end` is structured the same way; downstream
53
+ reporting can join on those.
package/i18n/en.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "nav.adminUsers.label": "Users",
3
+ "actions.openAdminUsers.label": "Admin users",
4
+ "actions.openAdminUsers.description": "Accounts that can sign in to the Admin UI"
5
+ }
package/i18n/pl.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "nav.adminUsers.label": "Użytkownicy",
3
+ "actions.openAdminUsers.label": "Użytkownicy panelu",
4
+ "actions.openAdminUsers.description": "Konta z dostępem do panelu administracyjnego"
5
+ }
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@endora-commerce/mod-admin-users",
3
+ "version": "0.100.0",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "Admin user accounts, sessions, and impersonation flows.",
7
+ "license": "MIT",
8
+ "endora": {
9
+ "type": "module",
10
+ "id": "admin_users"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/endora-commerce/endora-commerce.git",
15
+ "directory": "packages/modules/admin_users"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/manifest.d.ts",
23
+ "default": "./dist/manifest.js"
24
+ },
25
+ "./backend": {
26
+ "types": "./dist/backend/index.d.ts",
27
+ "default": "./dist/backend/index.js"
28
+ },
29
+ "./migrations": {
30
+ "types": "./dist/migrations/index.d.ts",
31
+ "default": "./dist/migrations/index.js"
32
+ },
33
+ "./admin": {
34
+ "types": "./dist/admin/index.d.ts",
35
+ "default": "./dist/admin/index.js"
36
+ },
37
+ "./tailwind.css": "./tailwind.css",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "i18n",
43
+ "docs",
44
+ "tailwind.css"
45
+ ],
46
+ "engines": {
47
+ "node": ">=22.18.0"
48
+ },
49
+ "peerDependencies": {
50
+ "@fastify/cookie": "^11",
51
+ "@mikro-orm/core": "^6",
52
+ "@mikro-orm/migrations": "^6",
53
+ "@mikro-orm/postgresql": "^6",
54
+ "fastify": "^5",
55
+ "lucide-react": "^1",
56
+ "react": "^19",
57
+ "react-router-dom": "^7",
58
+ "@endora-commerce/admin-kit": "0.100.0",
59
+ "@endora-commerce/contracts": "0.100.0",
60
+ "@endora-commerce/platform": "0.100.0"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "@endora-commerce/admin-kit": {
64
+ "optional": true
65
+ },
66
+ "lucide-react": {
67
+ "optional": true
68
+ },
69
+ "react": {
70
+ "optional": true
71
+ },
72
+ "react-router-dom": {
73
+ "optional": true
74
+ }
75
+ },
76
+ "devDependencies": {
77
+ "@fastify/cookie": "^11.0.2",
78
+ "@fastify/type-provider-zod": "^1.0.0",
79
+ "@mikro-orm/core": "^6.6.13",
80
+ "@mikro-orm/migrations": "^6.6.13",
81
+ "@mikro-orm/postgresql": "^6.6.13",
82
+ "@types/node": "^22.9.0",
83
+ "@types/react": "^19.2.14",
84
+ "fastify": "^5.12.5",
85
+ "lucide-react": "^1.11.0",
86
+ "react": "^19.2.5",
87
+ "react-router-dom": "^7.18.2",
88
+ "typescript": "^5.9.3",
89
+ "vitest": "^4.1.11",
90
+ "@endora-commerce/admin-kit": "0.100.0",
91
+ "@endora-commerce/contracts": "0.100.0",
92
+ "@endora-commerce/platform": "0.100.0"
93
+ },
94
+ "scripts": {
95
+ "build": "tsc -p tsconfig.build.json && tsc -p tsconfig.ui.json",
96
+ "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.ui.json --noEmit",
97
+ "lint": "eslint src",
98
+ "test": "vitest run"
99
+ }
100
+ }
package/tailwind.css ADDED
@@ -0,0 +1,14 @@
1
+ /* @endora-commerce/mod-admin-users — AUTO-GENERATED by `pnpm --filter backend run manifests:generate`.
2
+ *
3
+ * The `@source` directives this package asks its host to scan
4
+ * (`specs/110-instance-repository/contracts/admin-stylesheet-composition.md` R1).
5
+ * They resolve relative to **this file**, so they hold wherever the package is
6
+ * installed — a workspace link here, `node_modules` in a client's instance.
7
+ *
8
+ * The `dist` line is what a published tarball ships and is what an instance
9
+ * scans; the `src` line is inert there and is what keeps `pnpm --filter admin
10
+ * run dev` reading source in this repository. Do not edit: run
11
+ * `pnpm --filter backend run manifests:generate`.
12
+ */
13
+ @source "./dist/admin";
14
+ @source "./src/admin";