wcz-layout 6.7.2 → 9.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/dist/Approval-Co6D1BNq.mjs +194 -0
  2. package/dist/Approval-Co6D1BNq.mjs.map +1 -0
  3. package/dist/DialogsContext-DLqA8RJ_.mjs +7 -0
  4. package/dist/DialogsContext-DLqA8RJ_.mjs.map +1 -0
  5. package/dist/Email-BzQQkbe9.mjs +20 -0
  6. package/dist/Email-BzQQkbe9.mjs.map +1 -0
  7. package/dist/FileMeta-DDqUju1Y.mjs +19 -0
  8. package/dist/FileMeta-DDqUju1Y.mjs.map +1 -0
  9. package/dist/FileMeta-ILLTOjaM.d.mts +20 -0
  10. package/dist/NotificationContext-CgwUOeW0.mjs +7 -0
  11. package/dist/NotificationContext-CgwUOeW0.mjs.map +1 -0
  12. package/dist/QueryClientParam-CzaM3akD.d.mts +11 -0
  13. package/dist/RouterListItemButton-owZVvuC_.mjs +78 -0
  14. package/dist/RouterListItemButton-owZVvuC_.mjs.map +1 -0
  15. package/dist/User-1gKoYJvW.d.mts +12 -0
  16. package/dist/auth.d.mts +25 -0
  17. package/dist/auth.mjs +88 -0
  18. package/dist/auth.mjs.map +1 -0
  19. package/dist/authMiddleware--HdlhhZO.mjs +78 -0
  20. package/dist/authMiddleware--HdlhhZO.mjs.map +1 -0
  21. package/dist/components.d.mts +107 -0
  22. package/dist/components.mjs +1500 -0
  23. package/dist/components.mjs.map +1 -0
  24. package/dist/data/client.d.mts +3217 -0
  25. package/dist/data/client.mjs +187 -0
  26. package/dist/data/client.mjs.map +1 -0
  27. package/dist/data/server.d.mts +19 -0
  28. package/dist/data/server.mjs +16 -0
  29. package/dist/data/server.mjs.map +1 -0
  30. package/dist/entra-s4ZjHq5o.mjs +101 -0
  31. package/dist/entra-s4ZjHq5o.mjs.map +1 -0
  32. package/dist/env-CoveIivr.mjs +30 -0
  33. package/dist/env-CoveIivr.mjs.map +1 -0
  34. package/dist/file-C5-a_6W6.mjs +148 -0
  35. package/dist/file-C5-a_6W6.mjs.map +1 -0
  36. package/dist/file-DM1x40eJ.mjs +179 -0
  37. package/dist/file-DM1x40eJ.mjs.map +1 -0
  38. package/dist/hooks.d.mts +226 -0
  39. package/dist/hooks.mjs +1087 -0
  40. package/dist/hooks.mjs.map +1 -0
  41. package/dist/index.d.mts +48 -0
  42. package/dist/index.mjs +1944 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/middleware.d.mts +46 -0
  45. package/dist/middleware.mjs +27 -0
  46. package/dist/middleware.mjs.map +1 -0
  47. package/dist/models.d.mts +598 -0
  48. package/dist/models.mjs +74 -0
  49. package/dist/models.mjs.map +1 -0
  50. package/dist/msalServer-CkNOOjjH.mjs +44 -0
  51. package/dist/msalServer-CkNOOjjH.mjs.map +1 -0
  52. package/dist/peoplesoft-DIe8H1Nu.mjs +240 -0
  53. package/dist/peoplesoft-DIe8H1Nu.mjs.map +1 -0
  54. package/dist/peoplesoft-gKd-Jh5L.d.mts +1219 -0
  55. package/dist/useDialogs-BUzVrTSP.mjs +248 -0
  56. package/dist/useDialogs-BUzVrTSP.mjs.map +1 -0
  57. package/dist/user-Cen43mlr.d.mts +19 -0
  58. package/dist/utils-2XiozDlV.mjs +156 -0
  59. package/dist/utils-2XiozDlV.mjs.map +1 -0
  60. package/dist/utils-BuWEQOuy.d.mts +65 -0
  61. package/dist/utils.d.mts +5 -0
  62. package/dist/utils.mjs +5 -0
  63. package/dist/vite.d.mts +7 -0
  64. package/dist/vite.mjs +182 -0
  65. package/dist/vite.mjs.map +1 -0
  66. package/package.json +129 -62
  67. package/skills/client-db/SKILL.md +93 -0
  68. package/skills/data-grid/SKILL.md +142 -0
  69. package/skills/db-schema/SKILL.md +71 -0
  70. package/skills/dialogs/SKILL.md +79 -0
  71. package/skills/forms/SKILL.md +82 -0
  72. package/skills/general/SKILL.md +17 -0
  73. package/skills/notifications/SKILL.md +43 -0
  74. package/skills/routing/SKILL.md +128 -0
  75. package/skills/server-functions/SKILL.md +113 -0
  76. package/skills/services/SKILL.md +30 -0
  77. package/skills/services/docs/approval.md +257 -0
  78. package/skills/services/docs/email.md +32 -0
  79. package/skills/services/docs/file.md +81 -0
  80. package/skills/services/docs/peoplesoft.md +110 -0
  81. package/skills/start/SKILL.md +46 -0
  82. package/skills/start/steps/01-git-setup.md +11 -0
  83. package/skills/start/steps/02-project-name-setup.md +14 -0
  84. package/skills/start/steps/03-apm-setup.md +208 -0
  85. package/skills/start/steps/04-database-setup.md +39 -0
  86. package/skills/start/steps/05-entra-setup.md +59 -0
  87. package/skills/start/steps/06-vault-setup.md +70 -0
  88. package/skills/start/steps/07-generate-favicon.md +10 -0
  89. package/skills/start/steps/08-commit.md +15 -0
  90. package/dist/src/components/Layout.d.ts +0 -16
  91. package/dist/src/components/Layout.js +0 -122
  92. package/dist/src/components/Layout.js.map +0 -1
  93. package/dist/src/components/dataGrid/ChipInputCell.d.ts +0 -9
  94. package/dist/src/components/dataGrid/ChipInputCell.js +0 -17
  95. package/dist/src/components/dataGrid/ChipInputCell.js.map +0 -1
  96. package/dist/src/components/dataGrid/EditableColumnHeader.d.ts +0 -2
  97. package/dist/src/components/dataGrid/EditableColumnHeader.js +0 -7
  98. package/dist/src/components/dataGrid/EditableColumnHeader.js.map +0 -1
  99. package/dist/src/components/dataGrid/GridToolbar.d.ts +0 -8
  100. package/dist/src/components/dataGrid/GridToolbar.js +0 -40
  101. package/dist/src/components/dataGrid/GridToolbar.js.map +0 -1
  102. package/dist/src/components/dataGrid/TableContainer.d.ts +0 -3
  103. package/dist/src/components/dataGrid/TableContainer.js +0 -32
  104. package/dist/src/components/dataGrid/TableContainer.js.map +0 -1
  105. package/dist/src/components/form/FormAutocomplete.d.ts +0 -7
  106. package/dist/src/components/form/FormAutocomplete.js +0 -10
  107. package/dist/src/components/form/FormAutocomplete.js.map +0 -1
  108. package/dist/src/components/form/FormCheckbox.d.ts +0 -7
  109. package/dist/src/components/form/FormCheckbox.js +0 -11
  110. package/dist/src/components/form/FormCheckbox.js.map +0 -1
  111. package/dist/src/components/form/FormDatePicker.d.ts +0 -9
  112. package/dist/src/components/form/FormDatePicker.js +0 -19
  113. package/dist/src/components/form/FormDatePicker.js.map +0 -1
  114. package/dist/src/components/form/FormDateTimePicker.d.ts +0 -9
  115. package/dist/src/components/form/FormDateTimePicker.js +0 -19
  116. package/dist/src/components/form/FormDateTimePicker.js.map +0 -1
  117. package/dist/src/components/form/FormNumberField.d.ts +0 -12
  118. package/dist/src/components/form/FormNumberField.js +0 -12
  119. package/dist/src/components/form/FormNumberField.js.map +0 -1
  120. package/dist/src/components/form/FormRadioGroup.d.ts +0 -13
  121. package/dist/src/components/form/FormRadioGroup.js +0 -11
  122. package/dist/src/components/form/FormRadioGroup.js.map +0 -1
  123. package/dist/src/components/form/FormSlider.d.ts +0 -7
  124. package/dist/src/components/form/FormSlider.js +0 -11
  125. package/dist/src/components/form/FormSlider.js.map +0 -1
  126. package/dist/src/components/form/FormSubmitButton.d.ts +0 -5
  127. package/dist/src/components/form/FormSubmitButton.js +0 -13
  128. package/dist/src/components/form/FormSubmitButton.js.map +0 -1
  129. package/dist/src/components/form/FormSwitch.d.ts +0 -7
  130. package/dist/src/components/form/FormSwitch.js +0 -11
  131. package/dist/src/components/form/FormSwitch.js.map +0 -1
  132. package/dist/src/components/form/FormTextField.d.ts +0 -7
  133. package/dist/src/components/form/FormTextField.js +0 -11
  134. package/dist/src/components/form/FormTextField.js.map +0 -1
  135. package/dist/src/components/layout/AccountMenu.d.ts +0 -9
  136. package/dist/src/components/layout/AccountMenu.js +0 -44
  137. package/dist/src/components/layout/AccountMenu.js.map +0 -1
  138. package/dist/src/components/layout/DevelopmentBanner.d.ts +0 -7
  139. package/dist/src/components/layout/DevelopmentBanner.js +0 -29
  140. package/dist/src/components/layout/DevelopmentBanner.js.map +0 -1
  141. package/dist/src/components/layout/ErrorPage.d.ts +0 -2
  142. package/dist/src/components/layout/ErrorPage.js +0 -25
  143. package/dist/src/components/layout/ErrorPage.js.map +0 -1
  144. package/dist/src/components/layout/LayoutDialog.d.ts +0 -12
  145. package/dist/src/components/layout/LayoutDialog.js +0 -12
  146. package/dist/src/components/layout/LayoutDialog.js.map +0 -1
  147. package/dist/src/components/layout/LayoutSnackbar.d.ts +0 -8
  148. package/dist/src/components/layout/LayoutSnackbar.js +0 -25
  149. package/dist/src/components/layout/LayoutSnackbar.js.map +0 -1
  150. package/dist/src/components/layout/NavigationDrawer.d.ts +0 -11
  151. package/dist/src/components/layout/NavigationDrawer.js +0 -70
  152. package/dist/src/components/layout/NavigationDrawer.js.map +0 -1
  153. package/dist/src/components/layout/NotificationMenu.d.ts +0 -8
  154. package/dist/src/components/layout/NotificationMenu.js +0 -26
  155. package/dist/src/components/layout/NotificationMenu.js.map +0 -1
  156. package/dist/src/components/layout/TypographyWithIcon.d.ts +0 -7
  157. package/dist/src/components/layout/TypographyWithIcon.js +0 -22
  158. package/dist/src/components/layout/TypographyWithIcon.js.map +0 -1
  159. package/dist/src/components/layout/Unauthorized.d.ts +0 -2
  160. package/dist/src/components/layout/Unauthorized.js +0 -26
  161. package/dist/src/components/layout/Unauthorized.js.map +0 -1
  162. package/dist/src/contexts/LayoutContext.d.ts +0 -40
  163. package/dist/src/contexts/LayoutContext.js +0 -60
  164. package/dist/src/contexts/LayoutContext.js.map +0 -1
  165. package/dist/src/contexts/UserContext.d.ts +0 -24
  166. package/dist/src/contexts/UserContext.js +0 -55
  167. package/dist/src/contexts/UserContext.js.map +0 -1
  168. package/dist/src/hooks/FormHooks.d.ts +0 -46
  169. package/dist/src/hooks/FormHooks.js +0 -31
  170. package/dist/src/hooks/FormHooks.js.map +0 -1
  171. package/dist/src/hooks/UseSnackbar.d.ts +0 -10
  172. package/dist/src/hooks/UseSnackbar.js +0 -23
  173. package/dist/src/hooks/UseSnackbar.js.map +0 -1
  174. package/dist/src/hooks/UseUser.d.ts +0 -10
  175. package/dist/src/hooks/UseUser.js +0 -25
  176. package/dist/src/hooks/UseUser.js.map +0 -1
  177. package/dist/src/index.d.ts +0 -20
  178. package/dist/src/index.js +0 -15
  179. package/dist/src/index.js.map +0 -1
  180. package/dist/src/models/Error.d.ts +0 -6
  181. package/dist/src/models/Error.js +0 -2
  182. package/dist/src/models/Error.js.map +0 -1
  183. package/dist/src/models/KeycloakSettings.d.ts +0 -8
  184. package/dist/src/models/KeycloakSettings.js +0 -2
  185. package/dist/src/models/KeycloakSettings.js.map +0 -1
  186. package/dist/src/models/LayoutPaletteColorOptions.d.ts +0 -6
  187. package/dist/src/models/LayoutPaletteColorOptions.js +0 -2
  188. package/dist/src/models/LayoutPaletteColorOptions.js.map +0 -1
  189. package/dist/src/models/LayoutRoute.d.ts +0 -14
  190. package/dist/src/models/LayoutRoute.js +0 -2
  191. package/dist/src/models/LayoutRoute.js.map +0 -1
  192. package/dist/src/models/Notification.d.ts +0 -9
  193. package/dist/src/models/Notification.js +0 -2
  194. package/dist/src/models/Notification.js.map +0 -1
  195. package/dist/src/models/PeoplesoftDepartment.d.ts +0 -14
  196. package/dist/src/models/PeoplesoftDepartment.js +0 -2
  197. package/dist/src/models/PeoplesoftDepartment.js.map +0 -1
  198. package/dist/src/models/PeoplesoftEmployee.d.ts +0 -34
  199. package/dist/src/models/PeoplesoftEmployee.js +0 -2
  200. package/dist/src/models/PeoplesoftEmployee.js.map +0 -1
  201. package/dist/src/models/Snackbar.d.ts +0 -15
  202. package/dist/src/models/Snackbar.js +0 -2
  203. package/dist/src/models/Snackbar.js.map +0 -1
  204. package/dist/src/models/User.d.ts +0 -27
  205. package/dist/src/models/User.js +0 -11
  206. package/dist/src/models/User.js.map +0 -1
  207. package/dist/src/models/types/EmployeeCategoryGroup.d.ts +0 -1
  208. package/dist/src/models/types/EmployeeCategoryGroup.js +0 -2
  209. package/dist/src/models/types/EmployeeCategoryGroup.js.map +0 -1
  210. package/dist/src/models/types/EmployeeStatus.d.ts +0 -1
  211. package/dist/src/models/types/EmployeeStatus.js +0 -2
  212. package/dist/src/models/types/EmployeeStatus.js.map +0 -1
  213. package/dist/src/utils/Auth.d.ts +0 -12
  214. package/dist/src/utils/Auth.js +0 -49
  215. package/dist/src/utils/Auth.js.map +0 -1
  216. package/dist/src/utils/Fetches.d.ts +0 -5
  217. package/dist/src/utils/Fetches.js +0 -66
  218. package/dist/src/utils/Fetches.js.map +0 -1
  219. package/dist/src/utils/FormUtils.d.ts +0 -7
  220. package/dist/src/utils/FormUtils.js +0 -9
  221. package/dist/src/utils/FormUtils.js.map +0 -1
  222. package/dist/src/utils/Helpers.d.ts +0 -11
  223. package/dist/src/utils/Helpers.js +0 -26
  224. package/dist/src/utils/Helpers.js.map +0 -1
  225. package/dist/tsconfig.tsbuildinfo +0 -1
  226. package/src/components/Layout.tsx +0 -183
  227. package/src/components/dataGrid/ChipInputCell.tsx +0 -31
  228. package/src/components/dataGrid/EditableColumnHeader.tsx +0 -7
  229. package/src/components/dataGrid/GridToolbar.tsx +0 -63
  230. package/src/components/dataGrid/TableContainer.tsx +0 -39
  231. package/src/components/form/FormAutocomplete.tsx +0 -34
  232. package/src/components/form/FormCheckbox.tsx +0 -32
  233. package/src/components/form/FormDatePicker.tsx +0 -34
  234. package/src/components/form/FormDateTimePicker.tsx +0 -34
  235. package/src/components/form/FormNumberField.tsx +0 -33
  236. package/src/components/form/FormRadioGroup.tsx +0 -43
  237. package/src/components/form/FormSlider.tsx +0 -28
  238. package/src/components/form/FormSubmitButton.tsx +0 -29
  239. package/src/components/form/FormSwitch.tsx +0 -32
  240. package/src/components/form/FormTextField.tsx +0 -26
  241. package/src/components/layout/AccountMenu.tsx +0 -160
  242. package/src/components/layout/DevelopmentBanner.tsx +0 -54
  243. package/src/components/layout/ErrorPage.tsx +0 -34
  244. package/src/components/layout/LayoutDialog.tsx +0 -50
  245. package/src/components/layout/LayoutSnackbar.tsx +0 -44
  246. package/src/components/layout/NavigationDrawer.tsx +0 -131
  247. package/src/components/layout/NotificationMenu.tsx +0 -76
  248. package/src/components/layout/TypographyWithIcon.tsx +0 -35
  249. package/src/components/layout/Unauthorized.tsx +0 -37
  250. package/src/contexts/LayoutContext.tsx +0 -127
  251. package/src/contexts/UserContext.tsx +0 -88
  252. package/src/hooks/FormHooks.ts +0 -33
  253. package/src/hooks/UseSnackbar.tsx +0 -28
  254. package/src/hooks/UseUser.tsx +0 -29
  255. package/src/index.ts +0 -27
  256. package/src/models/Error.tsx +0 -6
  257. package/src/models/KeycloakSettings.ts +0 -8
  258. package/src/models/LayoutPaletteColorOptions.tsx +0 -7
  259. package/src/models/LayoutRoute.ts +0 -15
  260. package/src/models/Notification.ts +0 -10
  261. package/src/models/PeoplesoftDepartment.ts +0 -15
  262. package/src/models/PeoplesoftEmployee.ts +0 -35
  263. package/src/models/Snackbar.ts +0 -16
  264. package/src/models/User.ts +0 -13
  265. package/src/models/types/EmployeeCategoryGroup.ts +0 -1
  266. package/src/models/types/EmployeeStatus.ts +0 -1
  267. package/src/utils/Auth.ts +0 -58
  268. package/src/utils/Fetches.ts +0 -83
  269. package/src/utils/FormUtils.ts +0 -22
  270. package/src/utils/Helpers.ts +0 -27
  271. package/tsconfig.json +0 -29
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: db-schema
3
+ description: "Use when: defining or updating Drizzle ORM table schemas, relations, enums, migrations, or Zod schemas derived from database models."
4
+ ---
5
+
6
+ # Database Schema Patterns
7
+
8
+ ## Rules
9
+
10
+ - Always use `uuid` for primary keys, and `snakeCase` for generating tables.
11
+ - For `uuid` columns, do not generate random values in the schema. Client should generate UUIDs when creating new records.
12
+ - Always add `withTimezone: true` to timestamp columns.
13
+ - Always add `onDelete: "cascade"` on foreign keys for child/dependent tables.
14
+ - Define relations in a central `relations.ts` file.
15
+ - Generate Zod schemas with `createSelectSchema`; override fields with stricter rules (trim, min/max) where needed.
16
+ - Use `.transform()` on all Zod schemas that include related data to assign parent IDs.
17
+ - Do not auto-generate migrations unless the user explicitly asks. When asked, run `npm run db:generate`; migrations apply automatically at app startup while `DATABASE_AUTO_MIGRATE=true`.
18
+
19
+ ## File Placement
20
+
21
+ ```
22
+ drizzle-orm - defineRelations utility
23
+ drizzle-orm/pg-core - snakeCase table builder and column types
24
+ drizzle-orm/zod - createSelectSchema
25
+ zod - Zod
26
+ src/server/db/schemas/ - Drizzle table schemas and relations
27
+ src/server/db/migrations/ - Drizzle migration files
28
+ src/lib/schemas/ - Zod schemas (shared between client and server)
29
+ wcz-layout/utils - `t` translation function
30
+ ```
31
+
32
+ ## Examples
33
+
34
+ ```ts
35
+ // src/server/db/schemas/<feature>.ts
36
+ export const bookTable = snakeCase.table("books", {
37
+ id: uuid().primaryKey(),
38
+ title: text().notNull(),
39
+ libraryId: uuid()
40
+ .notNull()
41
+ .references(() => libraryTable.id, { onDelete: "cascade" }),
42
+ });
43
+
44
+ // src/server/db/schemas/relations.ts
45
+ export const relations = defineRelations(
46
+ { libraryTable, bookTable },
47
+ ({ one, many, libraryTable: library, bookTable: book }) => ({
48
+ libraryTable: {
49
+ books: many.bookTable(),
50
+ },
51
+ bookTable: {
52
+ library: one.libraryTable({ from: book.libraryId, to: library.id }),
53
+ },
54
+ }),
55
+ );
56
+
57
+ // src/lib/schemas/<feature>.ts
58
+ export const BookSchema = createSelectSchema(bookTable, {
59
+ title: (schema) =>
60
+ schema
61
+ .trim()
62
+ .min(1, t("Validation.Required"))
63
+ .max(255, t("Validation.MaxLength", { length: 255 })),
64
+ pages: PageSchema.array().min(1, t("Validation.Required")),
65
+ }).transform((data) => ({
66
+ ...data,
67
+ pages: data.pages.map((page) => ({ ...page, bookId: data.id })),
68
+ }));
69
+
70
+ export type Book = z.infer<typeof BookSchema>;
71
+ ```
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: dialogs
3
+ description: "Use when: creating or modifying alert dialogs, confirm dialogs, typed custom dialogs, or dialog-driven user flows."
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Always use `useDialogs()` for modal interactions.
9
+ - Use `confirm()` for destructive or user-confirmed actions.
10
+ - Use `alert()` for informational or error messages that require acknowledgement.
11
+ - Use `open()` for feature-specific custom dialogs with typed payloads.
12
+ - Custom dialogs must receive `DialogProps<T>`.
13
+ - Keep dialogs colocated inside `routes/feature/-components` when feature-specific.
14
+ - Always use translation; add new keys for feature-specific messages.
15
+ - Use notifications for lightweight feedback; dialogs when the user must decide or acknowledge.
16
+
17
+ ## File Placement
18
+
19
+ ```txt
20
+ src/components/dialogs/ — shared dialogs used across features
21
+ src/routes/<feature>s/-components/ — feature-scoped dialogs
22
+ wcz-layout/hooks — useDialogs hook, DialogProps type, useTranslation
23
+ src/lib/locales/ — translation keys
24
+ @mui/material — MUI Dialog components
25
+ ```
26
+
27
+ ## Examples
28
+
29
+ ```ts
30
+ // confirmation dialog
31
+ const { confirm } = useDialogs();
32
+ const { t } = useTranslation();
33
+
34
+ const confirmed = await confirm(t("DeleteConfirmation", { count: selectedIds.length }));
35
+ if (confirmed) await deleteFeature({ data: id });
36
+
37
+ // alert dialog
38
+ const { alert } = useDialogs();
39
+ const { t } = useTranslation();
40
+
41
+ try {
42
+ await saveFeature(values);
43
+ await alert(t("FeatureSavedSuccessfully"));
44
+ } catch (error) {
45
+ await alert(error instanceof Error ? error.message : t("UnknownError"));
46
+ }
47
+
48
+ // custom dialog
49
+ const { open } = useDialogs();
50
+
51
+ await open(EditFeatureDialog, { id });
52
+
53
+ // custom dialog component
54
+ interface Payload {
55
+ id: string;
56
+ }
57
+
58
+ export const EditFeatureDialog = ({
59
+ payload,
60
+ open,
61
+ onClose,
62
+ }: DialogProps<Payload>) => {
63
+ const { t } = useTranslation();
64
+
65
+ return (
66
+ <Dialog fullWidth open={open} onClose={() => onClose()}>
67
+ <DialogTitle>{t("EditFeature")}</DialogTitle>
68
+ <DialogContent>
69
+ {payload.id}
70
+ </DialogContent>
71
+ <DialogActions>
72
+ <Button onClick={() => onClose()}>
73
+ Close
74
+ </Button>
75
+ </DialogActions>
76
+ </Dialog>
77
+ );
78
+ };
79
+ ```
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: forms
3
+ description: "Use when: creating or modifying TanStack Form components, field layouts, validation schemas, submit handling, or custom form controls."
4
+ ---
5
+
6
+ # Form Patterns
7
+
8
+ ## Rules
9
+
10
+ - Always use `useLayoutForm` with pre-defined components.
11
+ - Define `width` for all form fields based on the expected content length.
12
+ - Reuse Zod schemas from `src/lib/schemas/` which are derived from Drizzle schemas with `createSelectSchema` from table schemas.
13
+ - Use translation for labels, helper text, validation messages and submit.
14
+ - Reset the form after successful create.
15
+ - Use one of the following field based on the use case: `Autocomplete`, `Checkbox`, `DatePicker`, `DateRangePicker`, `DateTimePicker`, `DateTimeRangePicker`, `NumberField`, `RadioGroup`, `Slider`, `SubmitButton`, `Switch`, `TextField`, `TimePicker`, or `TimeRangePicker`.
16
+
17
+ ## File Placement
18
+
19
+ ```
20
+ src/routes/<feature>s/-components/ - route-scoped forms
21
+ src/lib/schemas/ — Zod schemas (shared between client and server)
22
+ wcz-layout/hooks - useLayoutForm hook, useTranslation
23
+ ```
24
+
25
+ ## Examples
26
+
27
+ ```ts
28
+ // Form Component
29
+ interface FormProps {
30
+ defaultValues: Feature;
31
+ onSubmit: (value: Feature) => Promise<void>;
32
+ }
33
+
34
+ export const Form: FC<FormProps> = ({ defaultValues, onSubmit }) => {
35
+ const { t } = useTranslation();
36
+
37
+ const form = useLayoutForm({
38
+ defaultValues,
39
+ validators: { onChange: FeatureSchema },
40
+ onSubmit: async ({ value, formApi }) => {
41
+ await onSubmit(value);
42
+ formApi.reset();
43
+ },
44
+ });
45
+
46
+ return (
47
+ <form
48
+ onSubmit={(event) => {
49
+ event.preventDefault();
50
+ event.stopPropagation();
51
+ form.handleSubmit();
52
+ }}
53
+ >
54
+ {/* some styling */}
55
+ <form.AppField name="name">
56
+ {(field) => <field.TextField label={t("Feature.Name")} required sx={{ width: 420 }} />}
57
+ </form.AppField>
58
+ {/* some styling */}
59
+ <form.AppForm>
60
+ <form.SubmitButton variant="contained">{t("Submit")}</form.SubmitButton>
61
+ </form.AppForm>
62
+ </form>
63
+ );
64
+ };
65
+
66
+ // Autocomplete
67
+ <field.Autocomplete
68
+ options={options}
69
+ sx={{ width: 250 }}
70
+ autoHighlight
71
+ autoSelect
72
+ autoComplete
73
+ loading={isLoading}
74
+ textFieldProps={{
75
+ label: t("Customer"),
76
+ required: true,
77
+ }}
78
+ />
79
+
80
+ // Checkbox
81
+ <field.Checkbox label={t("IsThisTrue")} />
82
+ ```
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: general
3
+ description: "Use ALWAYS for project-wide conventions and coding standards. It defines the default style, rules, and best practices that apply to every file and feature."
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Generate modern ES6+ TypeScript with explicit types and never use `any`.
9
+ - Stick to double quotes, semicolons, and the `~/` alias for `src/` imports.
10
+ - Avoid `useMemo` / `useCallback`; the React Compiler handles memoization.
11
+ - Keep code self-documenting; only add comments to clarify non-obvious intent.
12
+ - When building UI, always design for both light and dark mode; this app uses `colorSchemeSelector: "data-mui-color-scheme"`, so prefer `theme.applyStyles("dark", ...)` for mode-specific styling.
13
+ - Before implementing features of external libraries, search for the latest docs on Context7 MCP.
14
+
15
+ ## When to Use This Skill
16
+
17
+ This is the default skill. Reference it in combination with more specific skills (e.g., `forms`, `tables`, `dialogs`) for targeted tasks.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: notifications
3
+ description: "Use when: displaying success, error, warning, or informational feedback with snackbars or async user actions."
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Use `useNotification()` for lightweight non-blocking user feedback.
9
+ - Always use translation; add new keys for feature-specific messages.
10
+ - Notifications are automatically queued by the provider and shown one at a time.
11
+ - `autoHideDuration` defaults to 5000 ms; override it (up to 10000 ms) only for messages that need more reading time.
12
+ - Use `severity: "success" | "info" | "warning" | "error"` consistently with the outcome.
13
+ - Use notifications for lightweight feedback; dialogs when the user must decide or acknowledge.
14
+
15
+ ## File Placement
16
+
17
+ ```txt
18
+ wcz-layout/hooks — useNotification hook, useTranslation
19
+ src/lib/locales/ — translation keys
20
+ ```
21
+
22
+ ## Examples
23
+
24
+ ```ts
25
+ // basic usage
26
+ const { notify } = useNotification();
27
+ const { t } = useTranslation();
28
+
29
+ notify(t("Feature.Created"), {
30
+ severity: "success",
31
+ autoHideDuration: 6000,
32
+ });
33
+
34
+ // error handling
35
+ try {
36
+ await deleteFeature({ data: id });
37
+ } catch (error) {
38
+ notify(error instanceof Error ? error.message : t("DeleteFailed"), {
39
+ severity: "error",
40
+ autoHideDuration: 10000,
41
+ });
42
+ }
43
+ ```
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: routing
3
+ description: "Use when: creating or modifying TanStack Router routes, feature folders, navigation, permissions, loaders, suspense flows, or route-scoped components/hooks."
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Always include `requirePermission("all")` in the route's `beforeLoad` function to enforce access control unless the route is meant to be public.
9
+ - Use `Route.useRouteContext()` to access the authenticated user. User can be `null` if the route doesn't include `requirePermission`.
10
+ - Use the route `loader` option to preload db collections. Preload only root-level collections.
11
+ - Create a `pendingComponent` for routes that suspend or preload meaningful data.
12
+ - Route names must always be kebab-case. Entity route names must always be plural.
13
+ - If a feature contains only one route, create a single file route: `src/routes/libraries.tsx`
14
+ - If a feature contains multiple related routes, create a folder: `src/routes/libraries/index.tsx`
15
+ - Colocate route-specific components/hooks inside `routes/<feature>/-components` or `-hooks`.
16
+ - Root-level `components/` and `hooks/` are only for code shared across multiple routes.
17
+ - After creating a new route, add or ask for a navigation item with a unique icon from `@mui/icons-material` in `src/routes/__root.tsx`.
18
+
19
+ ## Base Project Structure
20
+
21
+ ```txt
22
+ src/ # client-first architecture
23
+ ├── components/ # shared components across multiple routes
24
+ ├── db-collections/ # tanstack-db collections
25
+ ├── hooks/ # shared hooks across multiple routes
26
+ ├── lib/ # contains isomorphic/shared logic usable by both client and server
27
+ │ ├── auth/
28
+ │ │ ├── permissions.ts
29
+ │ │ └── scopes.ts
30
+ │ ├── locales/
31
+ │ │ ├── cs.json
32
+ │ │ └── en.json
33
+ │ └── schemas/ # shared zod schemas
34
+ ├── routes/ # TanStack Router file-based routing
35
+ │ ├── __root.tsx
36
+ │ ├── index.tsx
37
+ │ └── features/ # route group with multiple pages
38
+ │ ├── -components/ # components specific to feature routes
39
+ │ ├── -hooks/ # hooks specific to feature routes
40
+ │ ├── index.tsx
41
+ │ ├── create.tsx
42
+ │ ├── edit.$id.tsx
43
+ │ └── $id.tsx
44
+ ├── server/ # server-only code
45
+ │ ├── actions/
46
+ │ │ └── feature.ts # server functions
47
+ │ ├── db/
48
+ │ │ ├── migrations/
49
+ │ │ ├── schemas/ # drizzle database schemas
50
+ │ │ │ └── feature.ts
51
+ │ │ └── index.ts # drizzle db instance
52
+ │ └── middleware/
53
+ │ └── databaseMiddleware.ts
54
+ └── types/
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ ```ts
60
+ // imports
61
+ import { useDialogs, useTranslation } from "wcz-layout/hooks";
62
+ import { requirePermission, uuidv7 } from "wcz-layout/utils";
63
+
64
+ // src/routes/features/create.tsx
65
+ export const Route = createFileRoute("/features/create")({
66
+ component: RouteComponent,
67
+ beforeLoad: requirePermission("all"),
68
+ pendingComponent: FeatureSkeleton,
69
+ loader: () => {
70
+ featureCollection.preload();
71
+ },
72
+ });
73
+
74
+ function RouteComponent() {
75
+ const { t } = useTranslation();
76
+ const { alert, confirm } = useDialogs();
77
+ const { user } = Route.useRouteContext();
78
+ // route component code...
79
+ }
80
+
81
+ // __root.tsx
82
+ import { hasPermission } from "wcz-layout/utils";
83
+
84
+ const { user } = Route.useRouteContext();
85
+
86
+ const navigation: Navigation = [
87
+ {
88
+ kind: "item",
89
+ to: "/",
90
+ title: "Home",
91
+ icon: <Home />,
92
+ hidden: !hasPermission(user, "all"),
93
+ },
94
+ {
95
+ kind: "header",
96
+ title: "Documentation",
97
+ },
98
+ {
99
+ kind: "group",
100
+ title: "Components",
101
+ icon: <Widgets />,
102
+ children: [
103
+ {
104
+ kind: "item",
105
+ to: "/components/navigation",
106
+ title: "Navigation",
107
+ icon: <AccountTree />,
108
+ },
109
+ {
110
+ kind: "divider",
111
+ },
112
+ {
113
+ kind: "item",
114
+ to: "/components/forms",
115
+ title: "Forms",
116
+ icon: <Code />,
117
+ },
118
+ ],
119
+ },
120
+ ];
121
+
122
+ // Routes are public by default. Protect a route by adding requirePermission to
123
+ // its beforeLoad — it redirects to login when signed out, then checks the group.
124
+ export const Route = createFileRoute("/feature-name")({
125
+ component: RouteComponent,
126
+ beforeLoad: requirePermission("all"),
127
+ });
128
+ ```
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: server-functions
3
+ description: "Use when: creating or modifying TanStack Start server functions, REST routes, middleware, validation, database transactions, external service calls, or permission checks."
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Before generating code, clarify whether the feature should be exposed as public REST API routes or implemented as internal TanStack Start server functions (recommended), and what permission should be required for access.
9
+ - If permission is unknown, use `"all"`.
10
+ - Every server function MUST include `authorizationMiddleware` — server functions are callable RPC endpoints, so a route-level `requirePermission` in `beforeLoad` only hides the UI and does not protect them.
11
+ - Follow the chain order for server functions: `validator` → `middleware` → `handler`.
12
+ - In middleware, always follow this order: `validationMiddleware` → `authorizationMiddleware` → `databaseMiddleware` (reject unauthorized callers before opening a DB transaction).
13
+ - Use `validationMiddleware` only in REST API routes. Server functions use `.validator()`.
14
+ - `databaseMiddleware` wraps the handler in a DB transaction and sets `app.user_name` so audit triggers can record who made the change.
15
+ - Reuse schemas from `src/lib/schemas/`.
16
+
17
+ ## File Placement
18
+
19
+ ```
20
+ src/server/actions/ — server functions
21
+ src/routes/api/ — REST API routes
22
+ src/server/middleware/ — databaseMiddleware
23
+ wcz-layout/middleware/ — authorizationMiddleware, validationMiddleware
24
+ src/server/db/schemas/ — tables, enums, relations
25
+ src/lib/schemas/ — Zod schemas (shared between client and server)
26
+ src/lib/auth/permissions.ts — permission keys
27
+ ```
28
+
29
+ ## Examples
30
+
31
+ ```ts
32
+ // src/server/actions/<feature>.ts
33
+ export const selectFeatures = createServerFn()
34
+ .middleware([authorizationMiddleware("all"), databaseMiddleware])
35
+ .handler(async ({ context }) => {
36
+ return await context.db.select().from(featureTable);
37
+ });
38
+
39
+ export const insertFeature = createServerFn({ method: "POST" })
40
+ .validator(FeatureSchema)
41
+ .middleware([authorizationMiddleware("admin"), databaseMiddleware])
42
+ .handler(async ({ data, context }) => {
43
+ await context.db.insert(featureTable).values(data);
44
+ });
45
+
46
+ export const updateFeature = createServerFn({ method: "POST" })
47
+ .validator(FeatureSchema)
48
+ .middleware([authorizationMiddleware("admin"), databaseMiddleware])
49
+ .handler(async ({ data, context }) => {
50
+ await context.db.update(featureTable).set(data).where(eq(featureTable.id, data.id));
51
+ });
52
+
53
+ export const deleteFeature = createServerFn({ method: "POST" })
54
+ .validator(FeatureSchema.pick({ id: true }))
55
+ .middleware([authorizationMiddleware("admin"), databaseMiddleware])
56
+ .handler(async ({ data, context }) => {
57
+ await context.db.delete(featureTable).where(eq(featureTable.id, data.id));
58
+ });
59
+
60
+ // src/routes/api/<feature>s/index.ts
61
+ export const Route = createFileRoute("/api/features/")({
62
+ server: {
63
+ handlers: ({ createHandlers }) =>
64
+ createHandlers({
65
+ GET: {
66
+ middleware: [authorizationMiddleware("all"), databaseMiddleware],
67
+ handler: async ({ context }) => {
68
+ const items = await context.db.select().from(featureTable);
69
+ return Response.json(items);
70
+ },
71
+ },
72
+ POST: {
73
+ middleware: [
74
+ validationMiddleware(FeatureSchema),
75
+ authorizationMiddleware("admin"),
76
+ databaseMiddleware,
77
+ ],
78
+ handler: async ({ context }) => {
79
+ const [response] = await context.db
80
+ .insert(featureTable)
81
+ .values(context.data)
82
+ .returning();
83
+ return Response.json(response, { status: 201 });
84
+ },
85
+ },
86
+ }),
87
+ },
88
+ });
89
+
90
+ // src/routes/api/<feature>s/$id.ts
91
+ export const Route = createFileRoute("/api/features/$id")({
92
+ server: {
93
+ middleware: [authorizationMiddleware("admin"), databaseMiddleware],
94
+ handlers: ({ createHandlers }) =>
95
+ createHandlers({
96
+ PUT: {
97
+ middleware: [validationMiddleware(FeatureSchema)],
98
+ handler: async ({ params, context }) => {
99
+ await context.db
100
+ .update(featureTable)
101
+ .set(context.data)
102
+ .where(eq(featureTable.id, params.id));
103
+ return new Response(null, { status: 204 });
104
+ },
105
+ },
106
+ DELETE: async ({ params, context }) => {
107
+ await context.db.delete(featureTable).where(eq(featureTable.id, params.id));
108
+ return new Response(null, { status: 204 });
109
+ },
110
+ }),
111
+ },
112
+ });
113
+ ```
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: services
3
+ description: "Use when: integrating file, approval, PeopleSoft, email, or attendance services into your workflow."
4
+ ---
5
+
6
+ ## Info
7
+
8
+ You can read about each service in the links below. Services are categorized as either client or server exports, depending on their intended usage.
9
+
10
+ - **Client exports** — Contains `queryOptions` and `mutationOptions`; use for data fetching/mutations on the client with React Query.
11
+ - **Server exports** — Server functions; prefer calling mutations inside other server functions or database transactions.
12
+ - All mutation options take `{ queryClient }` so they can invalidate related queries.
13
+ - To read about a service, open the linked file in the **File** column directly.
14
+
15
+ ## Import Paths
16
+
17
+ - Client exports: `wcz-layout/data/client`
18
+ - Server exports: `wcz-layout/data/server`
19
+ - Schemas & Models: `wcz-layout/models`
20
+
21
+ ## Services
22
+
23
+ | Service | File | Summary |
24
+ | ---------- | ----------------------------------- | ----------------------------------------------------------------------- |
25
+ | file | [file.md](docs/file.md) | File metadata, thumbnails, binary download/open, upload, update, delete |
26
+ | approval | [approval.md](docs/approval.md) | Approval request lifecycle, approvers, flows, statuses, step results |
27
+ | peoplesoft | [peoplesoft.md](docs/peoplesoft.md) | Employee, manager, department, and company general manager lookups |
28
+ | email | [email.md](docs/email.md) | Server-only email sending with optional file attachment references |
29
+
30
+ > The attendance service is not available yet — do not generate code against it; tell the user it is coming in a future release.