@open-kingdom/shared-backend-data-access-users 0.0.2-13 → 0.0.2-15

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 (2) hide show
  1. package/README.md +158 -4
  2. package/package.json +3 -2
package/README.md CHANGED
@@ -1,7 +1,161 @@
1
- # data-access-users
1
+ # `@open-kingdom/shared-backend-data-access-users`
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ A NestJS module providing `UsersService` for User entity persistence via Drizzle ORM + SQLite, including bcrypt password hashing, full CRUD operations, and automatic admin user seeding on startup.
4
4
 
5
- ## Building
5
+ ---
6
6
 
7
- Run `nx build data-access-users` to build the library.
7
+ ## Exports
8
+
9
+ | Export | Kind | Description |
10
+ | ----------------------------------------- | -------------------- | -------------------------------------------------------------------------- |
11
+ | `OpenKingdomDataAccessBackendUsersModule` | `class` | Standard NestJS module. Provides and exports `UsersService`. |
12
+ | `DataAccessBackendUsersModule` | `class` | Alias for `OpenKingdomDataAccessBackendUsersModule`. |
13
+ | `UsersService` | `class` | Injectable service for all user persistence operations. |
14
+ | `users` | `BetterSQLite3Table` | Drizzle table definition for the `users` table. |
15
+ | `UsersTableName` | `string` | The literal string `'users'`. Used when constructing typed schema objects. |
16
+ | `User` | `type` | TypeScript type inferred from `users.$inferSelect`. |
17
+ | `NewUser` | `type` | TypeScript type inferred from `users.$inferInsert`. |
18
+
19
+ ---
20
+
21
+ ## Type Definitions
22
+
23
+ ### `users` Table Schema
24
+
25
+ The `users` SQLite table has the following columns:
26
+
27
+ | Column | Type | Constraints | Description |
28
+ | ------------ | --------- | --------------------------- | --------------------------------------------------- |
29
+ | `id` | `integer` | Primary key, auto-increment | Unique user identifier |
30
+ | `first_name` | `text` | Nullable | User's first name |
31
+ | `last_name` | `text` | Nullable | User's last name |
32
+ | `email` | `text` | Not null, unique | User's email address |
33
+ | `password` | `text` | Not null | bcrypt-hashed password; never returned in plaintext |
34
+
35
+ ### `User` Type
36
+
37
+ The `User` type is inferred from `users.$inferSelect` and has the following shape:
38
+
39
+ | Property | Type | Description |
40
+ | ----------- | ---------------- | -------------------------------------- |
41
+ | `id` | `number` | Auto-incremented primary key |
42
+ | `firstName` | `string \| null` | User's first name |
43
+ | `lastName` | `string \| null` | User's last name |
44
+ | `email` | `string` | Unique email address |
45
+ | `password` | `string` | bcrypt hash — never exposed to clients |
46
+
47
+ ### `NewUser` Type
48
+
49
+ The `NewUser` type is inferred from `users.$inferInsert`. All fields are the same as `User` except `id` is optional (omitted for auto-increment inserts) and `firstName`/`lastName` are also optional. When passed to `UsersService.create()`, the `password` field is plaintext — the service hashes it before storage.
50
+
51
+ ---
52
+
53
+ ## Module Registration
54
+
55
+ `OpenKingdomDataAccessBackendUsersModule` is a standard (non-dynamic) module. It does not call `register()` or `forRoot()`. Import it directly.
56
+
57
+ This module does **not** register the database connection itself. `DatabaseSetupModule.register()` must be registered globally (in the root `AppModule`) before this module is imported.
58
+
59
+ ```typescript
60
+ // some-feature.module.ts
61
+ import { Module } from '@nestjs/common';
62
+ import { OpenKingdomDataAccessBackendUsersModule } from '@open-kingdom/shared-backend-data-access-users';
63
+
64
+ @Module({
65
+ imports: [OpenKingdomDataAccessBackendUsersModule],
66
+ // UsersService is now available for injection in this module's providers
67
+ })
68
+ export class SomeFeatureModule {}
69
+ ```
70
+
71
+ When imported inside a dynamic module (e.g., `FeatureUserManagementModule`), the import is declared in the returned `DynamicModule` object's `imports` array — the same pattern applies.
72
+
73
+ ---
74
+
75
+ ## Configuration
76
+
77
+ No configuration options. The service resolves its database dependency via the global `DB_TAG` token provided by `DatabaseSetupModule`.
78
+
79
+ ---
80
+
81
+ ## UsersService API
82
+
83
+ ### Constructor Injection
84
+
85
+ ```typescript
86
+ import { UsersService } from '@open-kingdom/shared-backend-data-access-users';
87
+
88
+ @Injectable()
89
+ export class MyService {
90
+ constructor(private usersService: UsersService) {}
91
+ }
92
+ ```
93
+
94
+ ### Methods
95
+
96
+ | Method | Parameters | Returns | Description |
97
+ | ------------ | ------------------------ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | `findOne` | `email: string` | `Promise<User \| undefined>` | Finds a user by email address. Returns `undefined` if not found. |
99
+ | `findById` | `id: number` | `Promise<User \| undefined>` | Finds a user by primary key. Returns `undefined` if not found. |
100
+ | `findAll` | — | `Promise<User[]>` | Returns all users. |
101
+ | `create` | `data: Omit<User, 'id'>` | `Promise<User>` | Inserts a new user. Hashes the plaintext password with bcrypt (12 salt rounds) before storage. |
102
+ | `delete` | `id: number` | `Promise<void>` | Deletes a user by primary key. |
103
+ | `ensureUser` | `data: Omit<User, 'id'>` | `Promise<User \| undefined>` | Inserts a user only if no user with that email already exists. Returns the existing user if found. Password is hashed before storage (same as `create`). |
104
+
105
+ ### Lifecycle: `onModuleInit`
106
+
107
+ `UsersService` implements `OnModuleInit`. On application startup it calls `ensureUser` with a default admin account (`email: 'admin@admin.com'`, `password: 'admin'`, first and last name both `'Admin'`). This seeds a default admin user if the database is empty. **Change or remove this default credential in production.**
108
+
109
+ ---
110
+
111
+ ## Drizzle Schema Reference
112
+
113
+ The `users` table definition is exported from this package and must be included in the `schema` passed to `DatabaseSetupModule.register()` so that relational queries work correctly. The `UsersTableName` constant (`'users'`) can be used as a key when building typed schema composition objects.
114
+
115
+ ```typescript
116
+ import { users, UsersTableName } from '@open-kingdom/shared-backend-data-access-users';
117
+
118
+ DatabaseSetupModule.register({
119
+ schema: { [UsersTableName]: users, ...otherTables },
120
+ filename: 'app.db',
121
+ });
122
+ ```
123
+
124
+ The `invitations` table in `feature-user-management` references `users.id` via a foreign key, so the `users` table must be present in the schema whenever that module is used.
125
+
126
+ ---
127
+
128
+ ## Injecting UsersService in a Custom Module
129
+
130
+ ```typescript
131
+ import { Module } from '@nestjs/common';
132
+ import { Injectable } from '@nestjs/common';
133
+ import { OpenKingdomDataAccessBackendUsersModule, UsersService, User } from '@open-kingdom/shared-backend-data-access-users';
134
+
135
+ @Injectable()
136
+ export class ProfileService {
137
+ constructor(private usersService: UsersService) {}
138
+
139
+ async getProfile(id: number): Promise<Omit<User, 'password'> | undefined> {
140
+ const user = await this.usersService.findById(id);
141
+ if (!user) return undefined;
142
+ const { password: _, ...rest } = user;
143
+ return rest;
144
+ }
145
+ }
146
+
147
+ @Module({
148
+ imports: [OpenKingdomDataAccessBackendUsersModule],
149
+ providers: [ProfileService],
150
+ exports: [ProfileService],
151
+ })
152
+ export class ProfileModule {}
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Testing
158
+
159
+ ```bash
160
+ nx test @open-kingdom/shared-backend-data-access-users
161
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-kingdom/shared-backend-data-access-users",
3
- "version": "0.0.2-13",
3
+ "version": "0.0.2-15",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -17,6 +17,7 @@
17
17
  }
18
18
  },
19
19
  "files": [
20
+ "README.md",
20
21
  "dist",
21
22
  "!**/*.tsbuildinfo"
22
23
  ],
@@ -29,7 +30,7 @@
29
30
  },
30
31
  "dependencies": {
31
32
  "tslib": "^2.3.0",
32
- "@open-kingdom/shared-poly-util-constants": "0.0.2-13",
33
+ "@open-kingdom/shared-poly-util-constants": "0.0.2-15",
33
34
  "@nestjs/common": "^11.0.0",
34
35
  "drizzle-orm": "^0.44.5",
35
36
  "bcrypt": "^5.1.1"