Reference
Contracts
Stability policy and public contract boundaries for the Flashboard beta surface.
Stability policy
Flashboard currently exposes a beta contract surface.
Stable-intent layers
src/Contracts/*- route naming conventions under
flashboard.* - versioned screen payload envelope with
schema_version
Soft-stable layers
- builder implementations in
src/Core/*/Builders - runtime assembler internals
- layout payload details
Beta rules
- breaking changes are allowed until
1.0 - every breaking change must be documented in
CHANGELOG.md - payload schema changes must update
SchemaVersion - renamed contracts must include upgrade notes
Renderer contract
- JSON consumers should read
schema_version - normalized form fields expose stable renderer hints, including
input,textarea,select,checkbox,switch,date,file_upload,rich_text,relation_select, andrelation_multi_select - password fields use the normal
inputrenderer withinput_type=password; renderers must not persist or display hydrated secret values - file upload payloads may expose
existing_filesmetadata, but must not expose file contents or raw temporary upload details - relation select payloads may expose
relationship,related_model,related_resource,foreign_key,owner_key,record_key_name,related_table,title_attribute,search_columns,options_url,options_per_page,selected_option, andrelated_routes - relation multi-select payloads may expose
relationship,related_model,related_resource,related_table,pivot_table,foreign_pivot_key,related_pivot_key,parent_key,related_key,record_key_name,title_attribute,search_columns,options_url,options_per_page,max_items,selected_options, andrelated_routes relation_selectoptions are loaded through protected resource routes and returnitemsplusmeta.has_more/meta.next_page; selected values must be hydrated through the same related-resource query extensions and field-levelmodifyQueryUsing()rules as normal option pagesrelation_multi_selectuses the same protected options route, accepts repeatedselected[]values for selected hydration, submits an array of scalar related keys, and treats pivot attributes as out of scope- inverse relation manager payloads use
type=has_oneortype=has_manyand may exposerecords_url,options_url,actions,records,selected_record,selected_records,pagination,empty_state,related_model,related_resource,local_key,foreign_key,record_key_name,title_attribute,search_columns, andread_only - relation manager action payloads are explicit objects with
key,method,url,label,icon,visible, andrequires_confirmation; renderers should not infer mutation URLs from relation keys - relation manager records/options/mutations must be resolved server-side through protected resource routes, related resource query extensions, and per-manager query modifiers; selected IDs from clients are inputs to re-resolution, not trusted relationship metadata
- runtime hook payloads and record context redact password values and replace file values with minimal metadata before dispatch
- Blade consumers should treat layout state, overlays, and notifications as public payloads
Public resource API
- resource configuration is split into dedicated surfaces:
table(),form(),detail(),infolist(),actions(), andpages() detail()remains supported andinfolist()is its concept-aligned alias- typed schema nodes are the preferred package-facing API for columns, fields, sections, tabs, filters, scopes, and entries
- keyed typed schema factories accept
make(string $key, ?string $label = null); use the second argument for static labels and->label()for later overrides BelongsTo::make(string $key, ?string $label = null, ?string $relationship = null)adds an optional third relationship override while preserving the same label conventionBelongsToMany::make(string $key, ?string $label = null, ?string $relationship = null)declares a form-level pivot sync field; it requires a real EloquentBelongsToManyrelationship for persistence and may cap submitted arrays withmaxItems()HasOne::make(string $key, ?string $label = null, ?string $relationship = null)andHasMany::make(string $key, ?string $label = null, ?string $relationship = null)declare inverse relation managers; relationship inference is based on the key, whilerelationship()andresource()remain explicit overrides- relation query callbacks such as
BelongsTo::modifyQueryUsing(),BelongsToMany::modifyQueryUsing(),HasOne::modifyRecordsQueryUsing(),HasMany::modifyAttachOptionsQueryUsing(), and relation-managermodifyQueryUsing()are server-only closures, are never serialized into payloads, and must return an EloquentBuilder - legacy array definitions remain supported as a compatibility bridge during the DSL migration
- runtime consumers should depend on normalized payload output, not on ad hoc legacy keys
- table row action payloads are backend-driven and permission-aware; renderers should consume normalized row
actionsinstead of inventing view/edit/delete buttons - resource
actions()owns both executable resource actions and table row action declarations; renderers consume row-level payloads from rowactions
Authorization contract
policy()opt-in on resources- ability maps for actions, fields, and relations
- page access through
canAccess()