feat: uuid ids everywhere, pickers for linked tickets, @pi/ui checkboxes
- Postgres: every table has a uuid `id` (gen_random_uuid()); the event store keeps its relay order in `seq`, and the lookup tables their uniqueness in constraints of their own. - MongoDB: `_id` is Mongo's ObjectId; `id` is the domain id (the same uuid as the aggregate's stream in Postgres), unique, and every query goes by it. Production starts from empty databases. - Web: linking tickets and hanging one from a parent are picked from a searchable select (links across projects, parents within the project) instead of typing a key; every checkbox is @pi/ui's pi-checkbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,7 +79,7 @@ export class MongoFindProjectsRepository extends FindProjectsRepository {
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<ProjectReadModel | null> {
|
||||
const doc = await this.projects.findById(id).lean<ProjectDoc>();
|
||||
const doc = await this.projects.findOne({ id: id }).lean<ProjectDoc>();
|
||||
return doc ? toProject(doc) : null;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ export class MongoFindProjectsRepository extends FindProjectsRepository {
|
||||
userId: string,
|
||||
): Promise<ProjectRole | null> {
|
||||
const doc = await this.projects
|
||||
.findOne({ _id: projectId, memberIds: userId }, { members: 1 })
|
||||
.findOne({ id: projectId, memberIds: userId }, { members: 1 })
|
||||
.lean<Pick<ProjectDoc, 'members'>>();
|
||||
return doc?.members.find((m) => m.user.id === userId)?.role ?? null;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ export class MongoFindIssuesRepository extends FindIssuesRepository {
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<IssueReadModel | null> {
|
||||
const doc = await this.issues.findById(id).lean<IssueDoc>();
|
||||
const doc = await this.issues.findOne({ id: id }).lean<IssueDoc>();
|
||||
return doc ? issueFromDoc(doc) : null;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export class MongoFindIssuesRepository extends FindIssuesRepository {
|
||||
async findByIds(ids: string[]): Promise<IssueReadModel[]> {
|
||||
if (ids.length === 0) return [];
|
||||
const docs = await this.issues
|
||||
.find({ _id: { $in: ids } })
|
||||
.find({ id: { $in: ids } })
|
||||
.lean<IssueDoc[]>();
|
||||
return docs.map(issueFromDoc);
|
||||
}
|
||||
@@ -322,15 +322,15 @@ export class MongoFindIssuesRepository extends FindIssuesRepository {
|
||||
// Only the top of each tree: a ticket with subtasks under an epic is not one.
|
||||
const docs = await this.issues
|
||||
.find({
|
||||
_id: { $in: [...progress.keys()] },
|
||||
id: { $in: [...progress.keys()] },
|
||||
'parent.id': null,
|
||||
trashedAt: null,
|
||||
})
|
||||
.sort({ number: 1 })
|
||||
.lean<IssueDoc[]>();
|
||||
return docs.map((doc) => {
|
||||
const { _id: _ignored, ...row } = progress.get(doc._id) ?? {
|
||||
_id: doc._id,
|
||||
const { _id: _ignored, ...row } = progress.get(doc.id) ?? {
|
||||
_id: doc.id,
|
||||
total: 0,
|
||||
finished: 0,
|
||||
storyPoints: 0,
|
||||
@@ -456,7 +456,7 @@ export class MongoFindCommentsRepository extends FindCommentsRepository {
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<CommentReadModel | null> {
|
||||
const doc = await this.comments.findById(id).lean<CommentDoc>();
|
||||
const doc = await this.comments.findOne({ id: id }).lean<CommentDoc>();
|
||||
return doc ? commentFromDoc(doc) : null;
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ export class MongoFindReleasesRepository extends FindReleasesRepository {
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<ReleaseReadModel | null> {
|
||||
const doc = await this.releases.findById(id).lean<ReleaseDoc>();
|
||||
const doc = await this.releases.findOne({ id: id }).lean<ReleaseDoc>();
|
||||
return doc ? fromDoc(doc) : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user