diff --git a/src/shared/context/FestipodDataContext.tsx b/src/shared/context/FestipodDataContext.tsx index ec8c3d0..edcebe9 100644 --- a/src/shared/context/FestipodDataContext.tsx +++ b/src/shared/context/FestipodDataContext.tsx @@ -28,13 +28,22 @@ import { useBackend } from '../refine/RefineProvider'; // custom vars, so a bare `process.env.FESTIPOD_MULTISTORE` throws // "process is not defined" in the browser harness. Guard it. const MULTISTORE = typeof process !== 'undefined' && process?.env?.FESTIPOD_MULTISTORE === '1'; -// `FpEventShapeType` is NOT imported here any more: events go through Refine, and -// the resource → shape binding lives in refine/shapeTypes.ts. -import { - FpUserProfileShapeType, - FpParticipationShapeType, -} from '../shapes/orm/festipodShapes.shapeTypes'; -import type { FpEvent, FpUserProfile, FpParticipation } from '../shapes/orm/festipodShapes.typings'; +// NO ShapeType IMPORTED HERE ANY MORE: every entity reads through a Refine +// backend, and the resource → shape binding is the backend's business. +// The ORM generator emits BARE shape names (`Event`, `UserProfile`, …), taken from +// each shape's IRI local name. They are aliased back to the `Fp*` spelling HERE, +// at the import, so nothing downstream depends on the generator's naming: `Event` +// is a DOM global, and the bare names collide with the app's own vocabulary +// (`FpEventData` & co.). The prefix cannot be restored at the generator — the +// emitted name follows the shape IRI, and those IRIs are the persisted RDF +// classes, not ours to rename. Never edit the generated files; `build:orm` +// overwrites them. +import type { + Event as FpEvent, + MeetingPoint as FpMeetingPoint, + Participation as FpParticipation, + UserProfile as FpUserProfile, +} from '../shapes/orm/festipodShapes.typings'; import { bootstrapWallet, type BootstrapResult } from '../utils/ngBootstrap'; import { autoSeedEnabled, shouldAutoSeed } from '../utils/autoSeed'; diff --git a/src/shared/shapes/orm/festipodShapes.schema.ts b/src/shared/shapes/orm/festipodShapes.schema.ts index ca1636d..b950bd2 100644 --- a/src/shared/shapes/orm/festipodShapes.schema.ts +++ b/src/shared/shapes/orm/festipodShapes.schema.ts @@ -5,7 +5,7 @@ import type { Schema } from "@ng-org/shex-orm"; * festipodShapesSchema: Schema for festipodShapes * ============================================================================= */ -export const festipodShapesSchema: Schema = { +export const festipodShapesSchema = { "http://festipod.org/Event": { iri: "http://festipod.org/Event", predicates: [ @@ -22,63 +22,99 @@ export const festipodShapesSchema: Schema = { readablePredicate: "@type", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/title", readablePredicate: "title", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/description", readablePredicate: "description", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/date", readablePredicate: "date", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/location", readablePredicate: "location", }, { - dataTypes: [{ valType: "number" }], + dataTypes: [ + { + valType: "number", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/distance", readablePredicate: "distance", }, { - dataTypes: [{ valType: "number" }], + dataTypes: [ + { + valType: "number", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/participantCount", readablePredicate: "participantCount", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/coverImage", readablePredicate: "coverImage", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/hostName", readablePredicate: "hostName", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/hostInitials", @@ -102,35 +138,55 @@ export const festipodShapesSchema: Schema = { readablePredicate: "@type", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/name", readablePredicate: "name", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/initials", readablePredicate: "initials", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/username", readablePredicate: "username", }, { - dataTypes: [{ valType: "string" }], + dataTypes: [ + { + valType: "string", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/role", readablePredicate: "role", }, { - dataTypes: [{ valType: "boolean" }], + dataTypes: [ + { + valType: "boolean", + }, + ], maxCardinality: 1, minCardinality: 0, iri: "http://festipod.org/isPublic", @@ -154,21 +210,33 @@ export const festipodShapesSchema: Schema = { readablePredicate: "@type", }, { - dataTypes: [{ valType: "iri" }], + dataTypes: [ + { + valType: "iri", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/event", readablePredicate: "event", }, { - dataTypes: [{ valType: "iri" }], + dataTypes: [ + { + valType: "iri", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/user", readablePredicate: "user", }, { - dataTypes: [{ valType: "boolean" }], + dataTypes: [ + { + valType: "boolean", + }, + ], maxCardinality: 1, minCardinality: 1, iri: "http://festipod.org/isConfirmed", @@ -176,4 +244,98 @@ export const festipodShapesSchema: Schema = { }, ], }, -}; + "http://festipod.org/MeetingPoint": { + iri: "http://festipod.org/MeetingPoint", + predicates: [ + { + dataTypes: [ + { + valType: "iri", + literals: ["http://festipod.org/MeetingPoint"], + }, + ], + maxCardinality: 1, + minCardinality: 1, + iri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + readablePredicate: "@type", + }, + { + dataTypes: [ + { + valType: "iri", + }, + ], + maxCardinality: 1, + minCardinality: 1, + iri: "http://festipod.org/event", + readablePredicate: "event", + }, + { + dataTypes: [ + { + valType: "iri", + }, + ], + maxCardinality: 1, + minCardinality: 1, + iri: "http://festipod.org/host", + readablePredicate: "host", + }, + { + dataTypes: [ + { + valType: "string", + }, + ], + maxCardinality: 1, + minCardinality: 1, + iri: "http://festipod.org/title", + readablePredicate: "title", + }, + { + dataTypes: [ + { + valType: "string", + }, + ], + maxCardinality: 1, + minCardinality: 0, + iri: "http://festipod.org/description", + readablePredicate: "description", + }, + { + dataTypes: [ + { + valType: "string", + }, + ], + maxCardinality: 1, + minCardinality: 0, + iri: "http://festipod.org/place", + readablePredicate: "place", + }, + { + dataTypes: [ + { + valType: "string", + }, + ], + maxCardinality: 1, + minCardinality: 0, + iri: "http://festipod.org/time", + readablePredicate: "time", + }, + { + dataTypes: [ + { + valType: "string", + }, + ], + maxCardinality: 1, + minCardinality: 0, + iri: "http://festipod.org/inbox", + readablePredicate: "inbox", + }, + ], + }, +} as const satisfies Schema; diff --git a/src/shared/shapes/orm/festipodShapes.shapeTypes.ts b/src/shared/shapes/orm/festipodShapes.shapeTypes.ts index f115e47..27a5d3d 100644 --- a/src/shared/shapes/orm/festipodShapes.shapeTypes.ts +++ b/src/shared/shapes/orm/festipodShapes.shapeTypes.ts @@ -1,17 +1,30 @@ import type { ShapeType } from "@ng-org/shex-orm"; -import { festipodShapesSchema } from "./festipodShapes.schema"; -import type { FpEvent, FpUserProfile, FpParticipation } from "./festipodShapes.typings"; +import { festipodShapesSchema } from "./festipodShapes.schema.ts"; +import type { + Event, + UserProfile, + Participation, + MeetingPoint, +} from "./festipodShapes.typings.ts"; // ShapeTypes for festipodShapes -export const FpEventShapeType: ShapeType = { + +export const EventShapeType: ShapeType = { schema: festipodShapesSchema, shape: "http://festipod.org/Event", }; -export const FpUserProfileShapeType: ShapeType = { + +export const UserProfileShapeType: ShapeType = { schema: festipodShapesSchema, shape: "http://festipod.org/UserProfile", }; -export const FpParticipationShapeType: ShapeType = { + +export const ParticipationShapeType: ShapeType = { schema: festipodShapesSchema, shape: "http://festipod.org/Participation", }; + +export const MeetingPointShapeType: ShapeType = { + schema: festipodShapesSchema, + shape: "http://festipod.org/MeetingPoint", +}; diff --git a/src/shared/shapes/orm/festipodShapes.typings.ts b/src/shared/shapes/orm/festipodShapes.typings.ts index 0fa42a8..9b142c6 100644 --- a/src/shared/shapes/orm/festipodShapes.typings.ts +++ b/src/shared/shapes/orm/festipodShapes.typings.ts @@ -9,9 +9,9 @@ export type IRI = string; /** * Event Type */ -export interface FpEvent { +export interface Event { /** - * The graph IRI. + * The graph NURI. */ readonly "@graph": IRI; /** @@ -81,9 +81,9 @@ export interface FpEvent { /** * UserProfile Type */ -export interface FpUserProfile { +export interface UserProfile { /** - * The graph IRI. + * The graph NURI. */ readonly "@graph": IRI; /** @@ -129,9 +129,9 @@ export interface FpUserProfile { /** * Participation Type */ -export interface FpParticipation { +export interface Participation { /** - * The graph IRI. + * The graph NURI. */ readonly "@graph": IRI; /** @@ -161,3 +161,63 @@ export interface FpParticipation { */ isConfirmed: boolean; } + +/** + * MeetingPoint Type + */ +export interface MeetingPoint { + /** + * The graph NURI. + */ + readonly "@graph": IRI; + /** + * The subject IRI. + */ + readonly "@id": IRI; + /** + * Original IRI: http://www.w3.org/1999/02/22-rdf-syntax-ns#type + */ + "@type": "http://festipod.org/MeetingPoint"; + /** + * Reference to the public event this meeting point is anchored to + * + * Original IRI: http://festipod.org/event + */ + event: IRI; + /** + * Reference to the user hosting the meeting point + * + * Original IRI: http://festipod.org/host + */ + host: IRI; + /** + * The title of the meeting point + * + * Original IRI: http://festipod.org/title + */ + title: string; + /** + * A description of the meeting point + * + * Original IRI: http://festipod.org/description + */ + description?: string; + /** + * Where participants gather (e.g. 'Entrée principale, sous l'horloge') + * + * Original IRI: http://festipod.org/place + */ + place?: string; + /** + * When participants gather (display string) + * + * Original IRI: http://festipod.org/time + */ + time?: string; + /** + * NURI of the meeting point's inbox (wired in T02.b/c) + * + * Original IRI: http://festipod.org/inbox + */ + inbox?: string; +} diff --git a/src/shared/shapes/shex/festipodShapes.shex b/src/shared/shapes/shex/festipodShapes.shex index 380cb51..e35fbc7 100644 --- a/src/shared/shapes/shex/festipodShapes.shex +++ b/src/shared/shapes/shex/festipodShapes.shex @@ -47,3 +47,21 @@ fp:Participation { fp:isConfirmed xsd:boolean // rdfs:comment "Whether the participation is confirmed" ; } + +fp:MeetingPoint { + a [fp:MeetingPoint] ; + fp:event IRI + // rdfs:comment "Reference to the public event this meeting point is anchored to" ; + fp:host IRI + // rdfs:comment "Reference to the user hosting the meeting point" ; + fp:title xsd:string + // rdfs:comment "The title of the meeting point" ; + fp:description xsd:string ? + // rdfs:comment "A description of the meeting point" ; + fp:place xsd:string ? + // rdfs:comment "Where participants gather (e.g. 'Entrée principale, sous l'horloge')" ; + fp:time xsd:string ? + // rdfs:comment "When participants gather (display string)" ; + fp:inbox xsd:string ? + // rdfs:comment "NURI of the meeting point's inbox (wired in T02.b/c)" ; +} diff --git a/src/shared/test-harness/harness-ng.tsx b/src/shared/test-harness/harness-ng.tsx index 24ad660..e6edadb 100644 --- a/src/shared/test-harness/harness-ng.tsx +++ b/src/shared/test-harness/harness-ng.tsx @@ -17,11 +17,16 @@ import { useShapeSet, useShapeSubscription } from '../hooks/useShapeSet'; import { ng } from '@ng-org/web'; import type { DeepSignalSet } from '@ng-org/alien-deepsignals'; import { - FpEventShapeType, - FpUserProfileShapeType, - FpParticipationShapeType, + EventShapeType as FpEventShapeType, + ParticipationShapeType as FpParticipationShapeType, + UserProfileShapeType as FpUserProfileShapeType, } from '../shapes/orm/festipodShapes.shapeTypes'; -import type { FpEvent, FpUserProfile, FpParticipation } from '../shapes/orm/festipodShapes.typings'; +import type { + Event as FpEvent, + MeetingPoint as FpMeetingPoint, + Participation as FpParticipation, + UserProfile as FpUserProfile, +} from '../shapes/orm/festipodShapes.typings'; import { seedEvents, seedUsers, seedParticipations } from '../data/seedData'; import { ensureGraphNuri } from '../utils/ngGraph'; diff --git a/src/shared/test-harness/harness.tsx b/src/shared/test-harness/harness.tsx index 44ce979..999db7e 100644 --- a/src/shared/test-harness/harness.tsx +++ b/src/shared/test-harness/harness.tsx @@ -12,7 +12,12 @@ import React, { useEffect, useRef } from 'react'; import { createRoot } from 'react-dom/client'; import { deepSignal } from '@ng-org/alien-deepsignals'; import type { DeepSignalSet } from '@ng-org/alien-deepsignals'; -import type { FpEvent, FpUserProfile, FpParticipation } from '../shapes/orm/festipodShapes.typings'; +import type { + Event as FpEvent, + MeetingPoint as FpMeetingPoint, + Participation as FpParticipation, + UserProfile as FpUserProfile, +} from '../shapes/orm/festipodShapes.typings'; // ============================================================================ // Seed data — same events/users as the app's seedData.ts diff --git a/src/shared/utils/ngBootstrap.ts b/src/shared/utils/ngBootstrap.ts index 520e19e..d3e7fc5 100644 --- a/src/shared/utils/ngBootstrap.ts +++ b/src/shared/utils/ngBootstrap.ts @@ -14,7 +14,10 @@ * module runs outside the component tree. */ -import type { FpEvent, FpUserProfile } from '../shapes/orm/festipodShapes.typings'; +import type { + Event as FpEvent, + UserProfile as FpUserProfile, +} from '../shapes/orm/festipodShapes.typings'; import type { FpEventData, FpUserData } from '../data/types'; import { seedEvents, seedUsers } from '../data/seedData';