Scaffold a new Mongoose model with its full CRUD service.
The entity name is provided in the task prompt.
Files to create
Model — apps/api/src/models/<entity>.model.ts
import { Schema, model, Document, Types } from 'mongoose';
export interface I<Entity> extends Document {
userId: Types.ObjectId;
// entity-specific fields
createdAt: Date;
updatedAt: Date;
}
const <entity>Schema = new Schema<I<Entity>>(
{
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true,
},
// entity fields
},
{
timestamps: true, // handles createdAt/updatedAt automatically
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
// All indexes defined here — never outside the schema file
<entity>Schema.index({ userId: 1, createdAt: -1 });
export const <Entity>Model = model<I<Entity>>('<Entity>', <entity>Schema);
Service — apps/api/src/services/<entity>.service.ts
Five methods, fully typed:
get<Entity>s(userId: string): Promise<I<Entity>[]>- Filter:
{ userId: new Types.ObjectId(userId) }
- Filter:
get<Entity>ById(id: string, userId: string): Promise<I<Entity>>- Throw
ApiError.notFound('<Entity> not found')if not found — never return null
- Throw
create<Entity>(userId: string, data: Create<Entity>Input): Promise<I<Entity>>- Attach
userIdto the document before saving
- Attach
update<Entity>(id: string, userId: string, data: Update<Entity>Input): Promise<I<Entity>>- Filter by both
_idanduserId— throwApiError.notFoundif missing - Use
{ new: true }infindOneAndUpdate
- Filter by both
delete<Entity>(id: string, userId: string): Promise<void>- Filter by both
_idanduserId— throwApiError.notFoundif missing
- Filter by both
Rules
- Import
ApiErrorfromutils/api-error.ts— neverthrow new Error(...) - Every query includes
userIdas a filter — no cross-user access - Use
new Types.ObjectId(userId)when building ObjectId filters - Never expose raw Mongoose errors — catch and rethrow as
ApiError.internal(...) - Named exports only. No
any.
Verification
npx turbo lint --filter=@wealthwise/api
List all created file paths and the five service method signatures.