Ng eventually #1
@@ -0,0 +1,7 @@
|
||||
# Doc-debt — app-architecture
|
||||
|
||||
> Presence of a block = doc to update. Processed → delete the block; no blocks left → delete this file.
|
||||
> One block = one "big change": `why` + `files` + `verify` (leaves to review).
|
||||
|
||||
## Raw markers (consolidate into blocks, then delete)
|
||||
- TOUCHED src/shared/context/FestipodDataContext.tsx @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
@@ -0,0 +1,9 @@
|
||||
# Doc-debt — data-layer
|
||||
|
||||
> Presence of a block = doc to update. Processed → delete the block; no blocks left → delete this file.
|
||||
> One block = one "big change": `why` + `files` + `verify` (leaves to review).
|
||||
|
||||
## Raw markers (consolidate into blocks, then delete)
|
||||
- TOUCHED src/shared/shapes/shex/festipodShapes.shex @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
- TOUCHED src/shared/context/FestipodDataContext.tsx @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
- TOUCHED src/shared/data/shapeAdapters.ts @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
@@ -0,0 +1,7 @@
|
||||
# Doc-debt — tech-stack
|
||||
|
||||
> Presence of a block = doc to update. Processed → delete the block; no blocks left → delete this file.
|
||||
> One block = one "big change": `why` + `files` + `verify` (leaves to review).
|
||||
|
||||
## Raw markers (consolidate into blocks, then delete)
|
||||
- TOUCHED package.json @2026-08-17 (session 0b064e8b-1717-421f-a20e-a4318ad217b1)
|
||||
@@ -1178,6 +1178,12 @@ function useNgData(): FestipodDataContextValue {
|
||||
await openDocumentInbox(eventGraph);
|
||||
const eventId = await writeEntity(eventGraph, ENTITY_TYPE.event, {
|
||||
title: str(event.title), description: str(event.description), date: str(event.date),
|
||||
// `date` is the human LABEL the form composed; these four are the machine
|
||||
// values it collected, written UNALTERED as the form's own ISO forms
|
||||
// (`YYYY-MM-DD`, `HH:MM`). They are stored alongside the label, never
|
||||
// derived from it — the label is display text and cannot be parsed back.
|
||||
startDate: str(event.startDate), endDate: str(event.endDate),
|
||||
startTime: str(event.startTime), endTime: str(event.endTime),
|
||||
location: str(event.location), distance: flt(event.distance),
|
||||
// No host notion: the creator merely SIGNALS a public event and is NOT
|
||||
// obliged to participate, so the count starts at 0 (the owner-materializer
|
||||
@@ -1231,6 +1237,14 @@ function useNgData(): FestipodDataContextValue {
|
||||
if (updates.title !== undefined) persists.push(updateEntityField(graph, id, 'title', str(updates.title)));
|
||||
if (updates.description !== undefined) persists.push(updateEntityField(graph, id, 'description', str(updates.description)));
|
||||
if (updates.date !== undefined) persists.push(updateEntityField(graph, id, 'date', str(updates.date)));
|
||||
// The machine dates/times travel with the label, not instead of it. A field
|
||||
// arriving as `''` (the form's empty date input) CLEARS the triple rather than
|
||||
// leaving a stale value behind — that is `updateEntityField`'s empty handling,
|
||||
// and it is the right reading here: the user emptied the input.
|
||||
if (updates.startDate !== undefined) persists.push(updateEntityField(graph, id, 'startDate', str(updates.startDate)));
|
||||
if (updates.endDate !== undefined) persists.push(updateEntityField(graph, id, 'endDate', str(updates.endDate)));
|
||||
if (updates.startTime !== undefined) persists.push(updateEntityField(graph, id, 'startTime', str(updates.startTime)));
|
||||
if (updates.endTime !== undefined) persists.push(updateEntityField(graph, id, 'endTime', str(updates.endTime)));
|
||||
if (updates.location !== undefined) persists.push(updateEntityField(graph, id, 'location', str(updates.location)));
|
||||
if (updates.distance !== undefined) persists.push(updateEntityField(graph, id, 'distance', flt(updates.distance)));
|
||||
await Promise.all(persists).catch(err => console.error(`${logPrefix} persist event update failed:`, err));
|
||||
|
||||
@@ -37,6 +37,15 @@ export function adaptEvent(s: UnionSubject): FpEventData {
|
||||
title: one(s, 'title'),
|
||||
description: one(s, 'description'),
|
||||
date: one(s, 'date'),
|
||||
// The four machine values, read back exactly as stored (`YYYY-MM-DD`, `HH:MM`).
|
||||
// `undefined` — not `''` — when the triple is absent: the app type declares them
|
||||
// optional and the screens branch on their PRESENCE (`event.startTime && …`), so
|
||||
// an event written before these fields existed reads as an event without them
|
||||
// rather than one whose dates are blank strings.
|
||||
startDate: one(s, 'startDate') || undefined,
|
||||
endDate: one(s, 'endDate') || undefined,
|
||||
startTime: one(s, 'startTime') || undefined,
|
||||
endTime: one(s, 'endTime') || undefined,
|
||||
location: one(s, 'location'),
|
||||
distance: s.props[`${FP}distance`] ? num(s, 'distance') : undefined,
|
||||
participantCount: num(s, 'participantCount'),
|
||||
|
||||
@@ -54,6 +54,50 @@ export const festipodShapesSchema = {
|
||||
iri: "http://festipod.org/date",
|
||||
readablePredicate: "date",
|
||||
},
|
||||
{
|
||||
dataTypes: [
|
||||
{
|
||||
valType: "string",
|
||||
},
|
||||
],
|
||||
maxCardinality: 1,
|
||||
minCardinality: 0,
|
||||
iri: "http://festipod.org/startDate",
|
||||
readablePredicate: "startDate",
|
||||
},
|
||||
{
|
||||
dataTypes: [
|
||||
{
|
||||
valType: "string",
|
||||
},
|
||||
],
|
||||
maxCardinality: 1,
|
||||
minCardinality: 0,
|
||||
iri: "http://festipod.org/endDate",
|
||||
readablePredicate: "endDate",
|
||||
},
|
||||
{
|
||||
dataTypes: [
|
||||
{
|
||||
valType: "string",
|
||||
},
|
||||
],
|
||||
maxCardinality: 1,
|
||||
minCardinality: 0,
|
||||
iri: "http://festipod.org/startTime",
|
||||
readablePredicate: "startTime",
|
||||
},
|
||||
{
|
||||
dataTypes: [
|
||||
{
|
||||
valType: "string",
|
||||
},
|
||||
],
|
||||
maxCardinality: 1,
|
||||
minCardinality: 0,
|
||||
iri: "http://festipod.org/endTime",
|
||||
readablePredicate: "endTime",
|
||||
},
|
||||
{
|
||||
dataTypes: [
|
||||
{
|
||||
|
||||
@@ -40,6 +40,30 @@ export interface Event {
|
||||
* Original IRI: http://festipod.org/date
|
||||
*/
|
||||
date: string;
|
||||
/**
|
||||
* The day the event starts, as the ISO calendar date the form collects (YYYY-MM-DD) — stored unaltered, never derived from fp:date
|
||||
*
|
||||
* Original IRI: http://festipod.org/startDate
|
||||
*/
|
||||
startDate?: string;
|
||||
/**
|
||||
* The day the event ends, as an ISO calendar date (YYYY-MM-DD); absent for a single-day event
|
||||
*
|
||||
* Original IRI: http://festipod.org/endDate
|
||||
*/
|
||||
endDate?: string;
|
||||
/**
|
||||
* The time of day the event starts, as the form collects it (HH:MM)
|
||||
*
|
||||
* Original IRI: http://festipod.org/startTime
|
||||
*/
|
||||
startTime?: string;
|
||||
/**
|
||||
* The time of day the event ends (HH:MM)
|
||||
*
|
||||
* Original IRI: http://festipod.org/endTime
|
||||
*/
|
||||
endTime?: string;
|
||||
/**
|
||||
* The location of the event
|
||||
*
|
||||
|
||||
@@ -10,6 +10,14 @@ fp:Event {
|
||||
// rdfs:comment "A description of the event" ;
|
||||
fp:date xsd:string
|
||||
// rdfs:comment "The display date of the event (e.g. 'Lun. 16 - Ven. 20 fév.')" ;
|
||||
fp:startDate xsd:string ?
|
||||
// rdfs:comment "The day the event starts, as the ISO calendar date the form collects (YYYY-MM-DD) — stored unaltered, never derived from fp:date" ;
|
||||
fp:endDate xsd:string ?
|
||||
// rdfs:comment "The day the event ends, as an ISO calendar date (YYYY-MM-DD); absent for a single-day event" ;
|
||||
fp:startTime xsd:string ?
|
||||
// rdfs:comment "The time of day the event starts, as the form collects it (HH:MM)" ;
|
||||
fp:endTime xsd:string ?
|
||||
// rdfs:comment "The time of day the event ends (HH:MM)" ;
|
||||
fp:location xsd:string
|
||||
// rdfs:comment "The location of the event" ;
|
||||
fp:distance xsd:float ?
|
||||
|
||||
Reference in New Issue
Block a user