User HasOne Host
Commit Message
User HasOne Host
Users do _not_ automatically get a Host (special onboarding process for
becoming a host).
Each User can have at most one Host (unique index on user_id foreign key).
Sync association types.
```console
pnpm psy db:migrate
If migrations had already been run, after adding
a new association, one could run sync instead
(db:migrate runs sync implicitly):
pnpm psy sync
## Changes
```diff
diff --git a/api/src/app/models/User.ts b/api/src/app/models/User.ts
index 09fd61c..93297cb 100644
--- a/api/src/app/models/User.ts
+++ b/api/src/app/models/User.ts
@@ -2,6 +2,7 @@ import ApplicationModel from '@models/ApplicationModel.js'
import { Decorators } from '@rvoh/dream'
import { DreamColumn } from '@rvoh/dream/types'
import Guest from './Guest.js'
+import Host from './Host.js'
const deco = new Decorators<typeof User>()
@@ -22,4 +23,7 @@ export default class User extends ApplicationModel {
@deco.HasOne('Guest')
public guest: Guest
+
+ @deco.HasOne('Host')
+ public host: Host
}
diff --git a/api/src/db/migrations/1765411028183-create-host.ts b/api/src/db/migrations/1765411028183-create-host.ts
index fc937ae..4c9bc1f 100644
--- a/api/src/db/migrations/1765411028183-create-host.ts
+++ b/api/src/db/migrations/1765411028183-create-host.ts
@@ -9,7 +9,8 @@ export async function up(db: Kysely<any>): Promise<void> {
.primaryKey()
.defaultTo(sql`uuidv7()`),
)
- .addColumn('user_id', 'uuid', col => col.references('users.id').onDelete('restrict').notNull())
+ // added .unique() to `user_id`
+ .addColumn('user_id', 'uuid', col => col.references('users.id').onDelete('restrict').notNull().unique())
.addColumn('created_at', 'timestamp', col => col.notNull())
.addColumn('updated_at', 'timestamp', col => col.notNull())
.execute()
diff --git a/api/src/types/db.ts b/api/src/types/db.ts
index e236e7c..588e001 100644
--- a/api/src/types/db.ts
+++ b/api/src/types/db.ts
@@ -77,6 +77,13 @@ export interface Guests {
userId: string
}
+export interface Hosts {
+ createdAt: Timestamp
+ id: Generated<string>
+ updatedAt: Timestamp
+ userId: string
+}
+
export interface Users {
createdAt: Timestamp
email: string
@@ -86,10 +93,12 @@ export interface Users {
export interface DB {
guests: Guests
+ hosts: Hosts
users: Users
}
export class DBClass {
guests: Guests
+ hosts: Hosts
users: Users
}
diff --git a/api/src/types/dream.globals.ts b/api/src/types/dream.globals.ts
index 6c9f10f..f241f3d 100644
--- a/api/src/types/dream.globals.ts
+++ b/api/src/types/dream.globals.ts
@@ -57,5 +57,10 @@ us humans, he says:
*/
export const globalTypeConfig = {
- serializers: ['GuestSerializer', 'GuestSummarySerializer'],
+ serializers: [
+ 'GuestSerializer',
+ 'GuestSummarySerializer',
+ 'HostSerializer',
+ 'HostSummarySerializer',
+ ],
} as const
diff --git a/api/src/types/dream.ts b/api/src/types/dream.ts
index 28bcc2f..c3578c8 100644
--- a/api/src/types/dream.ts
+++ b/api/src/types/dream.ts
@@ -118,6 +118,64 @@ export const schema = {
},
},
},
+ hosts: {
+ serializerKeys: ['default', 'summary'],
+ scopes: {
+ default: [],
+ named: [],
+ },
+ nonJsonColumnNames: ['createdAt', 'id', 'updatedAt', 'userId'],
+ columns: {
+ createdAt: {
+ coercedType: {} as DateTime,
+ enumType: null,
+ enumArrayType: null,
+ enumValues: null,
+ dbType: 'timestamp without time zone',
+ allowNull: false,
+ isArray: false,
+ },
+ id: {
+ coercedType: {} as string,
+ enumType: null,
+ enumArrayType: null,
+ enumValues: null,
+ dbType: 'uuid',
+ allowNull: false,
+ isArray: false,
+ },
+ updatedAt: {
+ coercedType: {} as DateTime,
+ enumType: null,
+ enumArrayType: null,
+ enumValues: null,
+ dbType: 'timestamp without time zone',
+ allowNull: false,
+ isArray: false,
+ },
+ userId: {
+ coercedType: {} as string,
+ enumType: null,
+ enumArrayType: null,
+ enumValues: null,
+ dbType: 'uuid',
+ allowNull: false,
+ isArray: false,
+ },
+ },
+ virtualColumns: [],
+ associations: {
+ user: {
+ type: 'BelongsTo',
+ foreignKey: 'userId',
+ foreignKeyTypeColumn: null,
+ tables: ['users'],
+ optional: false,
+ requiredAndClauses: null,
+ passthroughAndClauses: null,
+ },
+ },
+ },
users: {
serializerKeys: [],
scopes: {
@@ -174,6 +232,15 @@ export const schema = {
requiredAndClauses: null,
passthroughAndClauses: null,
},
+ host: {
+ type: 'HasOne',
+ foreignKey: 'userId',
+ foreignKeyTypeColumn: null,
+ tables: ['hosts'],
+ optional: null,
+ requiredAndClauses: null,
+ passthroughAndClauses: null,
+ },
},
},
} as const
@@ -184,6 +251,7 @@ export const connectionTypeConfig = {
globalNames: {
models: {
Guest: 'guests',
+ Host: 'hosts',
User: 'users',
},
},