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:
2026-10-14 19:16:43 +02:00
parent 10c8f21ff4
commit 2c501a50d0
30 changed files with 292 additions and 207 deletions

View File

@@ -16,7 +16,7 @@ import {
untracked,
} from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { PiIconComponent, PiNoteComponent } from '@pi/ui';
import { PiCheckboxComponent, PiIconComponent, PiNoteComponent } from '@pi/ui';
import { GitIntegrationComponent } from '../ui/git-integration';
import { WebhooksComponent } from '../ui/webhooks';
import { TransferComponent } from '../ui/transfer';
@@ -57,6 +57,7 @@ function idFrom(name: string): string {
selector: 'ts-settings-page',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
PiCheckboxComponent,
RouterLink,
GitIntegrationComponent,
WebhooksComponent,
@@ -263,18 +264,16 @@ function idFrom(name: string): string {
})
"
/>
<label class="ts-check">
<input
type="checkbox"
[checked]="status.requiresReason"
(change)="
edit('statuses', i, {
requiresReason: $any($event.target).checked,
})
"
/>
<span class="visually-hidden">Pide motivo</span>
</label>
<pi-checkbox
class="ts-check"
[checked]="status.requiresReason"
(checkedChange)="
edit('statuses', i, { requiresReason: $event })
"
><span class="visually-hidden"
>Pide motivo</span
></pi-checkbox
>
<ng-container
[ngTemplateOutlet]="archive"
[ngTemplateOutletContext]="{
@@ -330,18 +329,15 @@ function idFrom(name: string): string {
@for (to of activeStatuses(); track to.id) {
<td>
@if (from.id !== to.id) {
<input
type="checkbox"
[attr.aria-label]="from.name + ' → ' + to.name"
<pi-checkbox
[checked]="allows(from.id, to.id)"
(change)="
toggleTransition(
from.id,
to.id,
$any($event.target).checked
)
(checkedChange)="
toggleTransition(from.id, to.id, $event)
"
/>
><span class="visually-hidden"
>{{ from.name }} → {{ to.name }}</span
></pi-checkbox
>
}
</td>
}