@@ -5,22 +5,25 @@ import {
55 getAllPersistedMockDbSnapshot ,
66 clearMockDbTables ,
77 getMockDbSessionUser ,
8- getMockDbSessionUsers ,
98 getStandaloneMockDbTables ,
9+ seedMockDbTables ,
1010 setMockDbSessionUser ,
1111} from "../src/engine/persistence/mock-db-store.js" ;
1212
1313const AUDIT_FIELDS = [ "createdAt" , "updatedAt" , "createdBy" , "updatedBy" ] ;
14- const TOOL_GROUP_ORDER = [ "project-journey" , "palette" , "asset" ] ;
14+ const TOOL_GROUP_ORDER = [ "workspace" , "game-design" , "game-configuration" , " project-journey", "palette" , "asset" ] ;
1515const TOOL_GROUP_LABELS = Object . freeze ( {
1616 asset : "Asset" ,
17+ "game-configuration" : "Game Configuration" ,
18+ "game-design" : "Game Design" ,
1719 palette : "Palette" ,
1820 "project-journey" : "Project Journey" ,
21+ workspace : "Workspace" ,
1922} ) ;
2023const STANDALONE_TABLE_LABELS = Object . freeze ( {
21- users : "Users" ,
22- actors : "Actors" ,
24+ user_roles : "User Roles" ,
2325} ) ;
26+ const IDENTITY_TABLE_GROUP = Object . freeze ( [ "users" , "user_roles" , "roles" ] ) ;
2427
2528class AdminDbViewer {
2629 constructor ( documentRef = document ) {
@@ -60,12 +63,21 @@ class AdminDbViewer {
6063 if ( ! button ) {
6164 return ;
6265 }
63- setMockDbSessionUser ( button . dataset . sessionUserButton || "user1 " ) ;
66+ setMockDbSessionUser ( button . dataset . sessionUserButton || "guest " ) ;
6467 this . createRepositories ( ) ;
6568 this . projectJourneyRepository . openProject ( "demo-project" ) ;
6669 this . render ( ) ;
6770 } ) ;
6871 this . clearButton ?. addEventListener ( "click" , ( ) => {
72+ const snapshot = getAllPersistedMockDbSnapshot ( ) ;
73+ if ( snapshot . cleared ) {
74+ seedMockDbTables ( ) ;
75+ this . createRepositories ( ) ;
76+ this . projectJourneyRepository . openProject ( "demo-project" ) ;
77+ this . activeFilter = "all" ;
78+ this . render ( ) ;
79+ return ;
80+ }
6981 if ( ! window . confirm ( "Clear all shared Mock DB records?" ) ) {
7082 return ;
7183 }
@@ -77,6 +89,14 @@ class AdminDbViewer {
7789 } ) ;
7890 }
7991
92+ renderClearSeedButton ( cleared ) {
93+ if ( ! this . clearButton ) {
94+ return ;
95+ }
96+ this . clearButton . textContent = cleared ? "Seed Mock DB" : "Clear Mock DB" ;
97+ this . clearButton . dataset . adminDbClearMode = cleared ? "seed" : "clear" ;
98+ }
99+
80100 createElement ( tagName , options = { } ) {
81101 const element = this . document . createElement ( tagName ) ;
82102 if ( options . className ) {
@@ -134,6 +154,8 @@ class AdminDbViewer {
134154 const snapshot = getAllPersistedMockDbSnapshot ( ) ;
135155 const tables = snapshot . tables ;
136156 const owners = snapshot . owners || { } ;
157+ const schemas = snapshot . schemas || { } ;
158+ const toolGroups = snapshot . toolGroups || { } ;
137159 const tableNamesForOwner = ( ownerId ) => Object . keys ( tables )
138160 . filter ( ( tableName ) => owners [ tableName ] === ownerId )
139161 . sort ( ) ;
@@ -142,9 +164,9 @@ class AdminDbViewer {
142164 const unownedTableNames = Object . keys ( tables )
143165 . filter ( ( tableName ) => ! toolOwnedTables . has ( tableName ) ) ;
144166 const standaloneTableNames = [
145- ...Object . keys ( STANDALONE_TABLE_LABELS ) . filter ( ( tableName ) => unownedTableNames . includes ( tableName ) ) ,
146- ...unownedTableNames . filter ( ( tableName ) => ! Object . hasOwn ( STANDALONE_TABLE_LABELS , tableName ) ) . sort ( ) ,
167+ ...unownedTableNames . filter ( ( tableName ) => ! IDENTITY_TABLE_GROUP . includes ( tableName ) ) . sort ( ) ,
147168 ] ;
169+ const identityTables = IDENTITY_TABLE_GROUP . filter ( ( tableName ) => unownedTableNames . includes ( tableName ) ) ;
148170 const groups = [
149171 {
150172 id : "all" ,
@@ -154,10 +176,16 @@ class AdminDbViewer {
154176 } ,
155177 ...toolGroupIds . map ( ( id ) => ( {
156178 id,
157- label : TOOL_GROUP_LABELS [ id ] ,
158- tableNames : tableNamesForOwner ( id ) ,
159- type : "tool" ,
160- } ) ) ,
179+ label : toolGroups [ id ] ?. label || TOOL_GROUP_LABELS [ id ] || id ,
180+ tableNames : tableNamesForOwner ( id ) ,
181+ type : "tool" ,
182+ } ) ) ,
183+ ...( identityTables . length ? [ {
184+ id : "user_roles" ,
185+ label : STANDALONE_TABLE_LABELS . user_roles ,
186+ tableNames : identityTables ,
187+ type : "table" ,
188+ } ] : [ ] ) ,
161189 ...standaloneTableNames . map ( ( tableName ) => ( {
162190 id : tableName ,
163191 label : STANDALONE_TABLE_LABELS [ tableName ] || tableName ,
@@ -166,7 +194,9 @@ class AdminDbViewer {
166194 } ) ) ,
167195 ] ;
168196 return {
197+ cleared : Boolean ( snapshot . cleared ) ,
169198 groups,
199+ schemas,
170200 tables,
171201 } ;
172202 }
@@ -175,7 +205,7 @@ class AdminDbViewer {
175205 return groups . find ( ( group ) => group . id === this . activeFilter ) || groups [ 0 ] ;
176206 }
177207
178- renderTable ( tableName , records ) {
208+ renderTable ( tableName , records , schemaFields = [ ] ) {
179209 const details = this . createElement ( "details" , {
180210 className : "vertical-accordion" ,
181211 } ) ;
@@ -196,7 +226,10 @@ class AdminDbViewer {
196226 } ) ;
197227 table . setAttribute ( "aria-label" , `${ tableName } records` ) ;
198228
199- const fields = this . tableFields ( records ) . filter ( ( field ) => field !== "key" ) ;
229+ const fields = [
230+ ...schemaFields ,
231+ ...this . tableFields ( records ) ,
232+ ] . filter ( ( field , index , allFields ) => field !== "key" && allFields . indexOf ( field ) === index ) ;
200233 const head = this . createElement ( "thead" ) ;
201234 const headerRow = this . createElement ( "tr" ) ;
202235 headerRow . append ( this . createElement ( "th" , { text : "Key" } ) ) ;
@@ -209,7 +242,7 @@ class AdminDbViewer {
209242 if ( ! records . length ) {
210243 const row = this . createElement ( "tr" ) ;
211244 const cell = this . createElement ( "td" , {
212- text : "No records in this table. Add records from its tool or clear browser mock DB storage to reseed defaults ." ,
245+ text : "No records in this table. Add records from its tool or use Seed Mock DB to restore baseline mock records ." ,
213246 } ) ;
214247 cell . colSpan = Math . max ( 1 , fields . length + 1 ) ;
215248 row . append ( cell ) ;
@@ -245,12 +278,11 @@ class AdminDbViewer {
245278 return details ;
246279 }
247280
248- renderTables ( tables ) {
281+ renderTables ( tables , schemas = { } ) {
249282 this . tablesRoot . replaceChildren ( ) ;
250283 Object . keys ( tables )
251- . sort ( )
252284 . forEach ( ( tableName ) => {
253- this . tablesRoot . append ( this . renderTable ( tableName , tables [ tableName ] ) ) ;
285+ this . tablesRoot . append ( this . renderTable ( tableName , tables [ tableName ] , schemas [ tableName ] || [ ] ) ) ;
254286 } ) ;
255287 }
256288
@@ -309,8 +341,17 @@ class AdminDbViewer {
309341 const noteTypeKeys = new Set ( ( tables . project_journey_note_types || [ ] ) . map ( ( type ) => type . key ) ) ;
310342 const noteKeys = new Set ( ( tables . project_journey_notes || [ ] ) . map ( ( note ) => note . key ) ) ;
311343 const userKeys = new Set ( ( tables . users || [ ] ) . map ( ( user ) => user . key ) ) ;
312- const actorKeys = new Set ( ( tables . actors || [ ] ) . map ( ( actor ) => actor . key ) ) ;
313- const actorUserKeys = new Set ( ( tables . actors || [ ] ) . map ( ( actor ) => actor . userKey ) ) ;
344+ const roleKeys = new Set ( ( tables . roles || [ ] ) . map ( ( role ) => role . key ) ) ;
345+ const systemRoleKeys = new Set (
346+ ( tables . roles || [ ] )
347+ . filter ( ( role ) => role . roleSlug === "system" || role . name === "system" )
348+ . map ( ( role ) => role . key ) ,
349+ ) ;
350+ const systemUserKeys = new Set (
351+ ( tables . user_roles || [ ] )
352+ . filter ( ( row ) => systemRoleKeys . has ( row . roleKey ) )
353+ . map ( ( row ) => row . userKey ) ,
354+ ) ;
314355 const activeTemplateKeys = new Set (
315356 ( tables . project_journey_templates || [ ] )
316357 . filter ( ( template ) => template . isActive )
@@ -328,14 +369,14 @@ class AdminDbViewer {
328369 ) ;
329370 return [
330371 {
331- name : "*.createdBy -> actors .key" ,
372+ name : "*.createdBy -> users .key" ,
332373 checked : allRecords . length ,
333- missing : allRecords . filter ( ( record ) => ! actorKeys . has ( record . createdBy ) ) ,
374+ missing : allRecords . filter ( ( record ) => ! userKeys . has ( record . createdBy ) ) ,
334375 } ,
335376 {
336- name : "*.updatedBy -> actors .key" ,
377+ name : "*.updatedBy -> users .key" ,
337378 checked : allRecords . length ,
338- missing : allRecords . filter ( ( record ) => ! actorKeys . has ( record . updatedBy ) ) ,
379+ missing : allRecords . filter ( ( record ) => ! userKeys . has ( record . updatedBy ) ) ,
339380 } ,
340381 {
341382 name : "project_journey_notes.typeKey -> project_journey_note_types.key" ,
@@ -354,9 +395,9 @@ class AdminDbViewer {
354395 } ,
355396 {
356397 name : "system project_journey_items.templateKey -> active project_journey_templates.key" ,
357- checked : ( tables . project_journey_items || [ ] ) . filter ( ( item ) => item . createdByType === "system" ) . length ,
398+ checked : ( tables . project_journey_items || [ ] ) . filter ( ( item ) => systemUserKeys . has ( item . createdBy ) ) . length ,
358399 missing : ( tables . project_journey_items || [ ] ) . filter (
359- ( item ) => item . createdByType === "system" && ! activeTemplateKeys . has ( item . templateKey ) ,
400+ ( item ) => systemUserKeys . has ( item . createdBy ) && ! activeTemplateKeys . has ( item . templateKey ) ,
360401 ) ,
361402 } ,
362403 {
@@ -365,14 +406,14 @@ class AdminDbViewer {
365406 missing : ( tables . project_journey_activity || [ ] ) . filter ( ( activity ) => ! noteKeys . has ( activity . noteKey ) ) ,
366407 } ,
367408 {
368- name : "actors .userKey -> users.key" ,
369- checked : ( tables . actors || [ ] ) . length ,
370- missing : ( tables . actors || [ ] ) . filter ( ( actor ) => ! userKeys . has ( actor . userKey ) ) ,
409+ name : "user_roles .userKey -> users.key" ,
410+ checked : ( tables . user_roles || [ ] ) . length ,
411+ missing : ( tables . user_roles || [ ] ) . filter ( ( row ) => ! userKeys . has ( row . userKey ) ) ,
371412 } ,
372413 {
373- name : "users.key -> actors.userKey " ,
374- checked : ( tables . users || [ ] ) . length ,
375- missing : ( tables . users || [ ] ) . filter ( ( user ) => ! actorUserKeys . has ( user . key ) ) ,
414+ name : "user_roles.roleKey -> roles.key " ,
415+ checked : ( tables . user_roles || [ ] ) . length ,
416+ missing : ( tables . user_roles || [ ] ) . filter ( ( row ) => ! roleKeys . has ( row . roleKey ) ) ,
376417 } ,
377418 {
378419 name : "palette_colors.projectId -> project_workspace_palette_globals.projectId" ,
@@ -486,9 +527,10 @@ class AdminDbViewer {
486527 ) ;
487528 this . renderFilters ( snapshot . groups ) ;
488529 this . renderSessionUser ( ) ;
530+ this . renderClearSeedButton ( snapshot . cleared ) ;
489531 this . renderDiagnostics ( snapshot . tables , snapshot . groups ) ;
490532 this . renderRelationships ( snapshot . tables ) ;
491- this . renderTables ( visibleTables ) ;
533+ this . renderTables ( visibleTables , snapshot . schemas ) ;
492534 if ( this . status ) {
493535 const recordCount = Object . values ( visibleTables ) . reduce ( ( total , rows ) => total + rows . length , 0 ) ;
494536 this . status . textContent = `Mock DB loaded ${ Object . keys ( visibleTables ) . length } table${ Object . keys ( visibleTables ) . length === 1 ? "" : "s" } and ${ recordCount } record${ recordCount === 1 ? "" : "s" } for ${ group . label } .` ;
0 commit comments