@sudobility/entity_service 1.0.2 → 1.0.4
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.
- package/CLAUDE.md +103 -59
- package/package.json +3 -3
package/CLAUDE.md
CHANGED
|
@@ -2,21 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
Shared backend library for multi-tenant entity/organization management.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**npm**: `@sudobility/entity_service` (public)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **Entity management**: Personal workspaces and organizations
|
|
9
|
-
- **Member management**: Role-based access control (admin, manager, viewer)
|
|
10
|
-
- **Invitation system**: Email invitations with auto-accept on signup
|
|
11
|
-
- **Permission checking**: Granular permission checks
|
|
12
|
-
- **Hono middleware**: Entity context injection for routes
|
|
7
|
+
## Tech Stack
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- **Language**: TypeScript (strict mode)
|
|
10
|
+
- **Runtime**: Bun
|
|
11
|
+
- **Build**: TypeScript compiler (dual ESM/CJS)
|
|
12
|
+
- **Test**: bun:test
|
|
13
|
+
- **Database**: PostgreSQL with Drizzle ORM
|
|
14
|
+
- **Framework**: Hono middleware
|
|
15
|
+
|
|
16
|
+
## Project Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/
|
|
20
|
+
├── index.ts # Main exports
|
|
21
|
+
├── types/ # Type definitions
|
|
22
|
+
│ ├── entity.ts # Entity types
|
|
23
|
+
│ ├── member.ts # Member/role types
|
|
24
|
+
│ └── invitation.ts # Invitation types
|
|
25
|
+
├── helpers/ # Business logic
|
|
26
|
+
│ ├── EntityHelper.ts # Entity CRUD operations
|
|
27
|
+
│ ├── MemberHelper.ts # Member management
|
|
28
|
+
│ └── InvitationHelper.ts # Invitation handling
|
|
29
|
+
├── middleware/ # Hono middleware
|
|
30
|
+
│ └── entityContext.ts # Entity context injection
|
|
31
|
+
├── schema/ # Drizzle schema templates
|
|
32
|
+
│ ├── entities.ts
|
|
33
|
+
│ ├── entityMembers.ts
|
|
34
|
+
│ └── entityInvitations.ts
|
|
35
|
+
└── utils/ # Utilities
|
|
36
|
+
└── permissions.ts # Permission checks
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun run build # Build ESM + CJS
|
|
43
|
+
bun run verify # All checks + build (use before commit)
|
|
44
|
+
bun test # Run tests
|
|
45
|
+
bun run typecheck # TypeScript check
|
|
46
|
+
bun run lint # Run ESLint
|
|
47
|
+
bun run clean # Remove dist/
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Key Concepts
|
|
51
|
+
|
|
52
|
+
### Entities
|
|
53
|
+
- **Personal Entity**: Auto-created for each user (entitySlug = userId)
|
|
54
|
+
- **Organization**: Created by users, has members with roles
|
|
15
55
|
|
|
16
|
-
###
|
|
56
|
+
### Roles & Permissions
|
|
17
57
|
|
|
58
|
+
| Permission | Admin | Manager | Viewer |
|
|
59
|
+
|------------|-------|---------|--------|
|
|
60
|
+
| View entity | Yes | Yes | Yes |
|
|
61
|
+
| Edit entity | Yes | No | No |
|
|
62
|
+
| Delete entity | Yes | No | No |
|
|
63
|
+
| Manage members | Yes | No | No |
|
|
64
|
+
| Invite members | Yes | No | No |
|
|
65
|
+
| Manage projects | Yes | Yes | No |
|
|
66
|
+
| Create projects | Yes | Yes | No |
|
|
67
|
+
| View projects | Yes | Yes | Yes |
|
|
68
|
+
|
|
69
|
+
### Invitation Flow
|
|
70
|
+
1. Admin creates invitation with email + role
|
|
71
|
+
2. Invitation stored with entity reference
|
|
72
|
+
3. On user signup, pending invitations auto-accepted
|
|
73
|
+
4. User becomes member of invited entities
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### Setup Helpers
|
|
18
78
|
```typescript
|
|
19
|
-
import { createEntityHelpers } from '@
|
|
79
|
+
import { createEntityHelpers } from '@sudobility/entity_service';
|
|
20
80
|
|
|
21
81
|
const helpers = createEntityHelpers({
|
|
22
82
|
db: drizzleDb,
|
|
@@ -28,7 +88,6 @@ const helpers = createEntityHelpers({
|
|
|
28
88
|
```
|
|
29
89
|
|
|
30
90
|
### Entity Operations
|
|
31
|
-
|
|
32
91
|
```typescript
|
|
33
92
|
// Get or create personal entity (on user login)
|
|
34
93
|
const personalEntity = await helpers.entity.getOrCreatePersonalEntity(userId, email);
|
|
@@ -43,36 +102,9 @@ const org = await helpers.entity.createOrganizationEntity(userId, {
|
|
|
43
102
|
const entities = await helpers.entity.getUserEntities(userId);
|
|
44
103
|
```
|
|
45
104
|
|
|
46
|
-
### Member Operations
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// Add member
|
|
50
|
-
await helpers.members.addMember(entityId, userId, EntityRole.MANAGER);
|
|
51
|
-
|
|
52
|
-
// Update role
|
|
53
|
-
await helpers.members.updateMemberRole(entityId, userId, EntityRole.ADMIN);
|
|
54
|
-
|
|
55
|
-
// Remove member
|
|
56
|
-
await helpers.members.removeMember(entityId, userId);
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Invitation Operations
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
// Create invitation
|
|
63
|
-
const invitation = await helpers.invitations.createInvitation(entityId, invitedBy, {
|
|
64
|
-
email: 'user@example.com',
|
|
65
|
-
role: EntityRole.VIEWER,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// Process pending invitations for new user
|
|
69
|
-
await helpers.invitations.processNewUserInvitations(userId, email);
|
|
70
|
-
```
|
|
71
|
-
|
|
72
105
|
### Hono Middleware
|
|
73
|
-
|
|
74
106
|
```typescript
|
|
75
|
-
import { createEntityContextMiddleware } from '@
|
|
107
|
+
import { createEntityContextMiddleware } from '@sudobility/entity_service';
|
|
76
108
|
|
|
77
109
|
const entityContext = createEntityContextMiddleware(config, {
|
|
78
110
|
getUserId: (c) => c.get('userId'),
|
|
@@ -88,10 +120,10 @@ app.get('/api/v1/entities/:entitySlug/projects', (c) => {
|
|
|
88
120
|
|
|
89
121
|
## Database Schema
|
|
90
122
|
|
|
91
|
-
|
|
123
|
+
Factory functions for creating tables in any PostgreSQL schema:
|
|
92
124
|
|
|
93
125
|
```typescript
|
|
94
|
-
import { createEntitiesTable, createEntityMembersTable } from '@
|
|
126
|
+
import { createEntitiesTable, createEntityMembersTable } from '@sudobility/entity_service';
|
|
95
127
|
import { pgSchema } from 'drizzle-orm/pg-core';
|
|
96
128
|
|
|
97
129
|
const mySchema = pgSchema('my_app');
|
|
@@ -100,25 +132,37 @@ export const entities = createEntitiesTable(mySchema, 'my_app');
|
|
|
100
132
|
export const entityMembers = createEntityMembersTable(mySchema, 'my_app');
|
|
101
133
|
```
|
|
102
134
|
|
|
103
|
-
##
|
|
135
|
+
## Peer Dependencies
|
|
104
136
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
| Manage members | ✓ | ✗ | ✗ |
|
|
111
|
-
| Invite members | ✓ | ✗ | ✗ |
|
|
112
|
-
| Manage projects | ✓ | ✓ | ✗ |
|
|
113
|
-
| Create projects | ✓ | ✓ | ✗ |
|
|
114
|
-
| View projects | ✓ | ✓ | ✓ |
|
|
115
|
-
| Manage API keys | ✓ | ✓ | ✗ |
|
|
116
|
-
| View API keys | ✓ | ✓ | ✓ |
|
|
117
|
-
|
|
118
|
-
## Build
|
|
137
|
+
Required in consuming app:
|
|
138
|
+
- `drizzle-orm` - Database ORM
|
|
139
|
+
- `hono` - Web framework (for middleware)
|
|
140
|
+
|
|
141
|
+
## Publishing
|
|
119
142
|
|
|
120
143
|
```bash
|
|
121
|
-
bun run
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
bun run verify # All checks
|
|
145
|
+
npm publish # Publish to npm
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Architecture
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
entity_service (this package)
|
|
152
|
+
↑
|
|
153
|
+
shapeshyft_api (backend)
|
|
154
|
+
sudojo_api (backend)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Code Patterns
|
|
158
|
+
|
|
159
|
+
### Error Handling
|
|
160
|
+
- Invalid entity slug: Return 404
|
|
161
|
+
- Permission denied: Return 403
|
|
162
|
+
- Duplicate invitation: Return 409
|
|
163
|
+
|
|
164
|
+
### Type Imports
|
|
165
|
+
```typescript
|
|
166
|
+
import type { Entity, EntityMember, EntityRole } from '@sudobility/entity_service';
|
|
167
|
+
import { EntityRole, hasPermission } from '@sudobility/entity_service';
|
|
124
168
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sudobility/entity_service",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Shared entity/organization management library for multi-tenant workspaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"author": "Sudobility",
|
|
55
55
|
"license": "MIT",
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@sudobility/types": "^1.9.
|
|
57
|
+
"@sudobility/types": "^1.9.42",
|
|
58
58
|
"drizzle-orm": "^0.45.0",
|
|
59
59
|
"hono": "^4.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@sudobility/types": "^1.9.
|
|
62
|
+
"@sudobility/types": "^1.9.42",
|
|
63
63
|
"@types/bun": "latest",
|
|
64
64
|
"@types/node": "^24.0.0",
|
|
65
65
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|