Ik heb de huidige PadelOS4-Sheet daadwerkelijk gecontroleerd. De voorbereidende tabellen bestaan en sluiten goed aan op PadelOS5: PAD4_SUBSCRIBERS, PAD4_ALERT_RULES, PAD4_BOOKING_CONNECTORS, PAD4_BOOKING_INTENTS, PAD4_MEMBERSHIPS, PAD4_WEATHER_CACHE en PAD4_NEWS_FEED. Ook staat in PAD4_BOOKING_INTENTS al expliciet AUTO_BOOK_ALLOWED naast CONFIRMATION_REQUIRED; dat is precies de veilige basis die we willen behouden. Bron: PadelOS4 bron-Sheet
Mijn architectuurkeuze is:
PadelOS5 krijgt een eigen Sheet voor persoonlijke state, maar PadelOS5 mag niet rechtstreeks schrijven in de interne PadelOS4-datatabellen.
PadelOS4 wordt de intelligence-provider.
PadelOS School wordt de school-provider.
PadelOS3/Identity wordt de identity authority.
PadelOS5 wordt orchestration + wallet + personal agent.
┌──────────────────────┐
│ PADELOS3 IDENTITY │
│ canonical USER_ID │
└──────────┬───────────┘
│
SAME USER_ID ───────┼─────────────────
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ PadelOS School │ │ PadelOS4 │ │ PadelOS5 │
│ lessons/player │ │ intelligence │ │ personal agent │
│ trainer/admin │ │ clubs/prices/etc │ │ wallet/intents │
└────────┬────────┘ └────────┬─────────┘ └────────┬────────┘
│ │ │
└──────────── API / DATA CONTRACT ──────────────────┘
De harde regel wordt dus:
USER_ID is wereldwijd binnen PadelOS onveranderlijk en uniek. Email is géén primary key.
Email kan veranderen. Een profielnaam kan veranderen. Een rol kan veranderen. USER_ID niet.
Er mag vanaf PadelOS5 geen derde loginimplementatie ontstaan.
De identity authority moet uiteindelijk één centrale service bevatten:
USER_ID
EMAIL_NORMALIZED
EMAIL_VERIFIED_AT
DISPLAY_NAME
ACCOUNT_STATUS
IDENTITY_VERSION
CREATED_AT
UPDATED_AT
Daarom verdwijnen conceptueel de losse relaties:
PAD4_SUBSCRIBERS.SUBSCRIBER_ID
PadelOS USERS.USER_ID
PadelOS5 USER_ID
niet onmiddellijk, maar wordt de relatie:
USER_ID
├── PAD4_SUBSCRIBER_ID legacy/external mapping
├── SCHOOL_PLAYER_ID
├── SCHOOL_TRAINER_ID
└── PAD5 profile/wallet records
Ik zou hiervoor een centrale mappinglaag gebruiken:
IDENTITY_LINKS
LINK_ID
USER_ID
SYSTEM
ENTITY_TYPE
ENTITY_ID
STATUS
CREATED_AT
UPDATED_AT
Bijvoorbeeld:
U_01 | PADELOS4 | SUBSCRIBER | SUB_0041
U_01 | SCHOOL | PLAYER | PLAYER_018
U_01 | SCHOOL | TRAINER | TRAINER_007
Zo kunnen bestaande IDs blijven bestaan zonder de systemen kapot te migreren.
Geen wachtwoorden in PadelOS4 of PadelOS5.
Ook geen tokens, API keys of sessiecookies in Sheets.
Alleen:
CREDENTIAL_REF
SECRET_PROVIDER
SECRET_SCOPE
LAST_VERIFIED_AT
STATUS
De bestaande CREDENTIAL_KEY in PAD4_MEMBERSHIPS en PAD4_BOOKING_CONNECTORS kan hiervoor dienen als reference, niet als geheim zelf.
Ik adviseer een aparte Sheet:
PadelOS5 · Personal Padel Agent
Waarom apart: PadelOS4 bevat nu al zowel landelijke intelligence als veel operationele/tabellarische data. Een persoonlijke wallet bevat privacygevoelige user-state, persoonlijke voorkeuren, accountreferenties en boekingsbesluiten. Dat hoort niet tussen landelijke prijs- en availability-history.
PadelOS5 wordt dus eigenaar van bijvoorbeeld:
PAD5_USER_PROFILE
PAD5_WALLET
PAD5_MEMBERSHIPS
PAD5_BOOKING_ACCOUNTS
PAD5_FAVORITES
PAD5_REGIONS
PAD5_BOOKING_INTENTS
PAD5_ALERT_RULES
PAD5_NOTIFICATION_PREFS
PAD5_NEWS_PREFS
PAD5_AGENT_RUNS
PAD5_AGENT_DECISIONS
PAD5_CONSENTS
PAD5_AUDIT_LOG
Maar belangrijke brongegevens worden niet gekopieerd.
Dus niet:
PAD5_CLUBS
PAD5_COURTS
PAD5_PRICE_HISTORY
PAD5_WEATHER
PAD5_NEWS
als duplicaatdatabase.
PadelOS5 bewaart daar alleen IDs/references naar.
Bijvoorbeeld:
PAD5_FAVORITES
FAVORITE_ID
USER_ID
OBJECT_TYPE
OBJECT_ID
RANK
NOTE
ACTIVE
CREATED_AT
Waar:
OBJECT_TYPE = CLUB | COURT | TRAINER | PLAYER
OBJECT_ID = PadelOS4 CLUB_ID / COURT_ID
of PadelOS School TRAINER_ID / PLAYER_ID
Dit wordt een kernobject van PadelOS5.
PAD5_MEMBERSHIPS
MEMBERSHIP_ID
USER_ID
CLUB_ID
PLATFORM
MEMBERSHIP_TYPE
MEMBERSHIP_NUMBER_REF
BOOKING_ACCOUNT_ID
RIGHTS_PROFILE
VALID_FROM
VALID_TO
STATUS
SOURCE
SOURCE_RECORD_ID
CREATED_AT
UPDATED_AT
Voorbeeld:
USER U001
TPC Daalmeer
CLUB_ID: ...
membership: MEMBER
federation: KNLTB
platform: Meet & Play
Peakz
membership: PUBLIC
platform: Playtomic
Plaza
membership: PUBLIC
platform: Playtomic
Belangrijk onderscheid:
membership zegt wat iemand mág.
booking account zegt via welk account die persoon toegang heeft.
Dus:
PAD5_BOOKING_ACCOUNTS
BOOKING_ACCOUNT_ID
USER_ID
PLATFORM
ACCOUNT_ALIAS
LOGIN_IDENTIFIER_HINT
CREDENTIAL_REF
AUTH_STATE
AUTHORIZED_SCOPES
LAST_AUTH_AT
EXPIRES_AT
STATUS
LOGIN_IDENTIFIER_HINT mag bijvoorbeeld een gedeeltelijk zichtbaar emailadres zijn.
Nooit:
PASSWORD
FULL_ACCESS_TOKEN
SESSION_COOKIE
in de Sheet.
De zes niveaus worden een formeel capability model:
1 BOOKING_LINK
2 ALERT_ONLY
3 ASSISTED_BOOKING
4 OFFICIAL_API_BOOKING
5 AUTHORIZED_BROWSER
6 AUTO_BOOK
Maar een connector heeft niet simpelweg één mode.
Ik zou capabilities afzonderlijk vastleggen:
CAN_READ_AVAILABILITY
CAN_READ_PRICE
CAN_OPEN_BOOKING
CAN_PREFILL_BOOKING
CAN_CREATE_BOOKING
CAN_CANCEL_BOOKING
CAN_BROWSER_AUTOMATE
CAN_AUTO_BOOK
De bestaande PadelOS4 PAD4_BOOKING_CONNECTORS bevat hier al een goede basis voor met onder meer MODE, AUTH_TYPE, AUTHORIZED, TERMS_OK, READ_AVAILABILITY, READ_PRICE, CREATE_BOOKING en CANCEL_BOOKING.
Daarboven komt in PadelOS5 user consent.
Een connector kan technisch AUTO_BOOK ondersteunen, terwijl gebruiker Stijn dat níet heeft toegestaan.
Daarom:
effective_permission =
connector_capability
AND platform_authorization
AND user_consent
AND membership_right
AND intent_permission
Pas als alle vijf true zijn mag een actie plaatsvinden.
Dit wordt het centrale object van de Personal Agent.
Voor:
Iedere dinsdag 19:00–21:00 in Alkmaar, minimaal 60 minuten, maximaal €35.
zou het model ongeveer zijn:
INTENT_ID
USER_ID
REGION = Alkmaar
CLUB_IDS = optional
DAY_OF_WEEK = TUE
TIME_FROM = 19:00
TIME_TO = 21:00
MIN_DURATION_MIN = 60
MAX_PRICE = 35.00
PRICE_SCOPE = USER_SHARE | FULL_COURT
INDOOR_PREF = ANY
COURT_TYPE = ANY
PARTICIPANTS_REQUIRED = 4
WEATHER_POLICY = CONSIDER
MEMBERSHIP_POLICY = ELIGIBLE_ONLY
BOOKING_MODE_MAX = ASSISTED_BOOKING
AUTO_BOOK_ALLOWED = false
CONFIRMATION_REQUIRED = true
RECURRENCE = WEEKLY
ACTIVE = true
Hier zou ik één belangrijke verbetering aanbrengen ten opzichte van de huidige PadelOS4-intent:
CLUB_ID mag optioneel zijn.
Een persoonlijke agent moet kunnen zoeken:
Alkmaar
en vervolgens meerdere clubs vergelijken.
Iedere intent gaat door exact dezelfde pipeline:
INTENT
↓
resolve USER_ID
↓
resolve region / candidate clubs
↓
PadelOS4 club intelligence
↓
availability
↓
price
↓
membership rights
↓
booking connector capability
↓
weather suitability
↓
user preferences
↓
rank candidates
↓
decision
Een kandidaat krijgt bijvoorbeeld intern:
availability_score
price_score
distance_score
membership_score
weather_score
favorite_score
booking_friction_score
en daarna:
MATCH_SCORE
Maar ook de reden wordt opgeslagen:
Padelclub X
20:00–21:00
€31
indoor
membership valid
preferred club
booking via Playtomic
score: 92
Dat is belangrijk voor uitlegbaarheid.
Een alert en een booking intent zijn niet hetzelfde.
Alert: informeer mij.
Intent: probeer een geschikte concrete speelmogelijkheid te vinden en begeleid mij verder.
Daarom:
PAD5_ALERT_RULES
voor dingen als:
Waarschuw mij iedere maandag wanneer de banen voor volgende week vrijkomen.
en:
PAD5_BOOKING_INTENTS
voor:
Zoek dinsdagavond een baan.
Alerts mogen verschillende triggers krijgen:
SCHEDULED
AVAILABILITY_FOUND
PRICE_BELOW
BOOKING_WINDOW_OPEN
COURT_RELEASED
WEATHER_CHANGED
NEWS_MATCH
MEMBERSHIP_EXPIRING
PadelOS5 moet zelf geen weerprovider gaan pollen.
De bestaande PAD4_WEATHER_CACHE bevat al onder andere:
CLUB_ID
REGION
FORECAST_AT
TEMP_C
PRECIP_MM
PRECIP_PROB
WIND_KMH
GUST_KMH
CONDITION
OUTDOOR_PLAY_SCORE
CONFIDENCE
Dat is bijna precies wat de agent nodig heeft.
PadelOS5 vraagt dus bijvoorbeeld:
GET /v1/weather?club_id=...&from=...&to=...
en gebruikt dat alleen voor beslissingen.
Voor indoor banen:
weather impact ≈ 0
Voor outdoor:
rain probability
wind
gusts
temperature
outdoor play score
kunnen ranking beïnvloeden.
Ook hier geen kopie van de volledige nieuwsfeed.
PadelOS4 blijft eigenaar van:
PAD4_NEWS_FEED
met onder andere CATEGORY, TITLE, SUMMARY, CLUB_ID, LOCATION, SOURCE_URL, SOURCE_NAME en CONFIDENCE.
PadelOS5 bewaart alleen:
PAD5_NEWS_PREFS
PAD5_NEWS_STATE
Bijvoorbeeld:
USER_ID
REGIONS
CLUB_IDS
CATEGORIES
PRICES
NEW_CLUBS
COURT_CHANGES
TOURNAMENTS
OPENINGS
BOOKING_CHANGES
WEATHER
MARK_READ
LAST_SEEN_AT
De persoonlijke feed ontstaat runtime:
PadelOS4 news
+
Mijn clubs
Mijn regio's
Mijn favorieten
Mijn memberships
Mijn booking intents
↓
personal ranking
Dus niet:
nieuws kopiëren per gebruiker, maar landelijk nieuws personaliseren per gebruiker.
Dit is de belangrijkste grens vóór we Code.gs schrijven.
PadelOS5 mag PadelOS4 benaderen via een beperkte service API:
GET /clubs
GET /clubs/{clubId}
GET /clubs/{clubId}/courts
GET /availability
GET /prices
GET /weather
GET /news
GET /booking-connectors
Writes:
POST /booking-intents
PATCH /booking-intents/{id}
POST /subscriptions
PATCH /subscriptions/{id}
maar niet rechtstreeks naar Sheet-ranges.
Nog beter is uiteindelijk dat PadelOS5 zijn eigen intent bezit en PadelOS4 alleen een intelligence-request ontvangt:
POST /availability/search
met:
{
"region": "Alkmaar",
"date": "...",
"time_from": "19:00",
"time_to": "21:00",
"duration_min": 60,
"max_price": 35
}
Dat geeft veel betere scheiding.
PadelOS5 heeft alleen read-oriented persoonlijke endpoints nodig zoals:
GET /me/player
GET /me/trainer
GET /me/lessons
GET /me/players
GET /me/trainers
GET /me/payments
allemaal geïdentificeerd vanuit:
USER_ID
Niet:
email=...
Daarmee kan de app later zonder extra login tonen:
Mijn spelers
Mijn trainers
Mijn lessen
Mijn betalingen
Ik zou hier een bijzonder harde regel van maken.
DEFAULT:
AUTO_BOOK_ALLOWED = false
CONFIRMATION_REQUIRED = true
AUTO_BOOK kan alleen aan wanneer tegelijk aanwezig zijn:
verified identity
+
active booking account
+
valid credential reference
+
connector supports booking
+
platform authorization valid
+
terms accepted
+
membership allows booking
+
explicit user consent
+
intent-specific auto-book permission
En zelfs dan:
MAX_PRICE
DATE/TIME
CLUB/REGION
DURATION
PARTICIPANTS
moeten binnen het expliciete consent vallen.
Geen stilzwijgende uitbreiding van toestemming.
Voor elke belangrijke agentactie:
EVENT_ID
USER_ID
INTENT_ID
EVENT_TYPE
ACTOR
CONNECTOR_ID
INPUT_REF
DECISION
REASON
CONSENT_ID
RESULT
CREATED_AT
Bijvoorbeeld:
AVAILABILITY_CHECKED
MATCH_FOUND
ALERT_SENT
BOOKING_PAGE_OPENED
BOOKING_CONFIRMATION_REQUESTED
BOOKING_AUTHORIZED
BOOKING_CREATED
BOOKING_FAILED
BOOKING_CANCELLED
Daarmee kunnen we altijd reconstrueren:
wat deed de agent, waarom, en met welke toestemming?
PADELOS3 / IDENTITY
OWNS:
USER_ID
login
mail verification
sessions
profile identity
permissions
PADELOS SCHOOL
OWNS:
players
trainers
lessons
school planning
school financial/admin data
PADELOS4
OWNS:
clubs
locations
courts
prices
availability observations
history
booking connector capabilities
news
weather
predictions
PADELOS5
OWNS:
membership wallet
booking-account references
favorites
regions
personal preferences
booking intents
personal alerts
consents
agent decisions
personal feed state
PadelOS5 krijgt dus een eigen Sheet.
Maar:
PadelOS5 wordt géén vierde silo.
De eigen Sheet bevat uitsluitend persoonlijke agent-state en references. PadelOS4 blijft authoritative voor landelijke intelligence en PadelOS School blijft authoritative voor schooldata.
En boven alles:
ONE HUMAN
=
ONE USER_ID
=
PadelOS3
=
PadelOS School
=
PadelOS4
=
PadelOS5
Dit sluit ook aan op de PadelOS-engineeringregel om eerst schema, rollen/identity en datagrenzen vast te leggen vóór Code.gs en Index.html.
DONE: systeemgrenzen, owner-model, unified identity-principe, Membership Wallet, alerts, booking-intent, weather, newsfeed en securitymodel zijn nu vastgelegd.
WORKING: formeel PadelOS5 ↔ PadelOS4 API Data Contract v1.
TODO: exacte velden voor PAD5_*, endpoint request/response-schema's, identity migration van SUBSCRIBER_ID → USER_ID, consentmodel en capability matrix.
BLOCKED: productie-Code.gs en Index.html blijven bewust geblokkeerd totdat dit contract definitief is.
NEXT: maak nu één formeel PADELOS5_DATA_CONTRACT_V1.md met alle PAD5_* tabellen, primary/foreign keys, API-endpoints en voorbeeld-JSON. Dat moet onze bouwspecificatie worden vóór er één regel PadelOS5-productiecode komt.
PadelOS4 — Intelligence Engine
Wat bestaat er?
Wat kost het?
Wat is beschikbaar?
Wat verandert?
Wat gebeurt er in de markt?
Wat verwachten we?
PadelOS5 — Personal Padel Agent
Waar wil ik spelen?
Wanneer?
Met wie?
Welke lidmaatschappen heb ik?
Wat wil ik maximaal betalen?
Wanneer moet ik boeken?
Meld mij zodra iets vrijkomt.
Help mij reserveren.
Boek automatisch wanneer ik dat expliciet heb toegestaan.
Ook jouw andere voorbeeld past er direct in:
iedere maandag 08:00 moet ik mijn baan voor volgende week reserveren.
Dat kan eerst als herinnering werken.
Later:
ALERT_ONLY
→ "Je kunt nu boeken."
daarna:
ASSISTED_BOOKING
→ juiste club/datum/tijd openen en gebruiker bevestigt.
en uiteindelijk, alleen waar de officiële/geautoriseerde connector het toestaat:
AUTO_BOOK
→ voorwaarden kloppen
→ prijs ≤ maximum
→ juiste club
→ juiste lidmaatschap
→ gewenste baan beschikbaar
→ boeking uitvoeren.
Dit vind ik een belangrijk PadelOS5-probleem.
In plaats van de gebruiker steeds zelf te laten denken:
KNLTB account A
uitloggen
account B
andere club
Playtomic account
Meet & Play
eigen clubportal...
maakt PadelOS een eigen Membership Wallet:
Ik werk dit nu uit als PadelOS4 = landelijke data-/monitorlaag en PadelOS5 = boekings-/alert-/user-automationlaag, maar zonder de twee onnodig uit elkaar te trekken. Eerst lees ik de actuele v4.1-code die we net hebben gemaakt; daarna maak ik één nieuwe complete set met de workflow, extra Sheet-schema, alerts, subscriptions en voorbereidende booking-connectors.
Daarna zou ik niet meteen PadelOS5 gaan programmeren. Eerst moeten we PadelOS4 één cruciale stap verder brengen: de Nederlandse clubdatabase veel completer maken en per club automatisch vaststellen welk bookingplatform en welke databron beschikbaar is. Dán weten we voor welke honderden clubs PUBLIC, Playtomic, Meet & Play, KNLTB, eigen booking of een andere connector nodig is.
Ik maak de volgende stap nu als PadelOS4 v4.2 = Monitor + Alerts + Booking Intelligence.
De kern blijft dezelfde Sheet, maar ik voeg expliciete lagen toe voor gebruikersabonnementen, baanbeschikbaarheid, boekingsintenties, club-lidmaatschappen, officiële connectors, AI/browser-jobs en weer. Belangrijk: automatische boeking wordt alleen voorbereid via officiële API of expliciet geautoriseerde browserconnector; captcha/MFA/voorwaarden worden nooit omzeild.
Ik heb hiervoor de connectorarchitectuur al toegevoegd.
Vier niveaus:
BOOKING_LINK
→ officiële boekingspagina openen.
OFFICIAL_API
→ echte availability/prices/bookings via geautoriseerde API.
AUTHORIZED_BROWSER
→ een expliciet toegestaan eigen/testaccount waarmee een browseragent de bookingflow mag doorlopen.
IMPORT_FEED
→ club levert gegevens rechtstreeks.
Dat is technisch sterker.
PAD4_AI_JOBS kan opdrachten bevatten als:
CHECK_PRICE
CHECK_AVAILABILITY
CHECK_COURT_COUNT
CHECK_NEW_LOCATION
CHECK_EVENT
CHECK_TRAINERS
CHECK_BOOKING_WINDOW