create-snapify-app 0.0.0-stage → 1.1.0

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 (614) hide show
  1. package/LICENSE.md +24 -0
  2. package/README.md +55 -2
  3. package/bin/create-snapify-app.mjs +174 -0
  4. package/lib/args.mjs +59 -0
  5. package/lib/copy.mjs +44 -0
  6. package/lib/env.mjs +84 -0
  7. package/lib/prompt.mjs +63 -0
  8. package/package.json +33 -4
  9. package/template/.env.example +79 -0
  10. package/template/.github/workflows/ci.yml +23 -0
  11. package/template/.github/workflows/deploy.yml +26 -0
  12. package/template/.github/workflows/ping.yml +8 -0
  13. package/template/.github/workflows/release.yml +67 -0
  14. package/template/.snapify-install.json +5 -0
  15. package/template/CHANGELOG.md +28 -0
  16. package/template/LICENSE +14 -0
  17. package/template/README.md +287 -0
  18. package/template/administrator.html +23 -0
  19. package/template/apps/client/src/App.tsx +765 -0
  20. package/template/apps/client/src/auth.css +400 -0
  21. package/template/apps/client/src/lib/api.ts +22 -0
  22. package/template/apps/client/src/main.tsx +20 -0
  23. package/template/apps/community/src/App.tsx +592 -0
  24. package/template/apps/community/src/main.tsx +20 -0
  25. package/template/apps/community/src/styles.css +24 -0
  26. package/template/apps/developers/src/App.tsx +643 -0
  27. package/template/apps/developers/src/main.tsx +17 -0
  28. package/template/apps/developers/src/pages.tsx +1587 -0
  29. package/template/apps/developers/src/styles.css +98 -0
  30. package/template/apps/developers/src/ui.tsx +179 -0
  31. package/template/apps/landing/src/App.tsx +598 -0
  32. package/template/apps/landing/src/LegalPages.tsx +158 -0
  33. package/template/apps/landing/src/OrderPage.tsx +381 -0
  34. package/template/apps/landing/src/SeoPages.tsx +923 -0
  35. package/template/apps/landing/src/copy.ts +195 -0
  36. package/template/apps/landing/src/main.tsx +20 -0
  37. package/template/apps/landing/src/styles.css +803 -0
  38. package/template/apps/landing/src/types.ts +19 -0
  39. package/template/apps/marketplace/src/App.tsx +1229 -0
  40. package/template/apps/marketplace/src/developer/DeveloperApp.tsx +1266 -0
  41. package/template/apps/marketplace/src/main.tsx +20 -0
  42. package/template/apps/marketplace/src/styles.css +1001 -0
  43. package/template/apps/shared/AuthContext.tsx +65 -0
  44. package/template/apps/shared/Logo.tsx +33 -0
  45. package/template/apps/shared/api.ts +47 -0
  46. package/template/apps/shared/ui.tsx +128 -0
  47. package/template/apps/superadmin/src/App.tsx +1264 -0
  48. package/template/apps/superadmin/src/lib/api.ts +20 -0
  49. package/template/apps/superadmin/src/lib/hooks.ts +20 -0
  50. package/template/apps/superadmin/src/main.tsx +16 -0
  51. package/template/apps/superadmin/src/pages/ClientsPage.tsx +185 -0
  52. package/template/apps/superadmin/src/pages/InvoicesPage.tsx +157 -0
  53. package/template/apps/superadmin/src/pages/NewsletterPage.tsx +212 -0
  54. package/template/apps/superadmin/src/pages/OrdersPage.tsx +195 -0
  55. package/template/apps/superadmin/src/pages/PaymentsPage.tsx +150 -0
  56. package/template/apps/superadmin/src/pages/PayoutsPage.tsx +133 -0
  57. package/template/apps/superadmin/src/pages/PublishersPage.tsx +151 -0
  58. package/template/apps/superadmin/src/pages/SeoControlPage.tsx +692 -0
  59. package/template/apps/superadmin/src/pages/SettingsPage.tsx +199 -0
  60. package/template/apps/superadmin/src/pages/SystemPage.tsx +109 -0
  61. package/template/apps/superadmin/src/pages/TicketsPage.tsx +201 -0
  62. package/template/apps/superadmin/src/pages/UsersPage.tsx +167 -0
  63. package/template/client.html +21 -0
  64. package/template/community/hamdiayari/akhbar/README.md +23 -0
  65. package/template/community/hamdiayari/akhbar/screenshot.jpg +0 -0
  66. package/template/community/hamdiayari/akhbar/snapify.theme.json +76 -0
  67. package/template/community/hamdiayari/akhbar/src/Brand.tsx +26 -0
  68. package/template/community/hamdiayari/akhbar/src/Footer.tsx +182 -0
  69. package/template/community/hamdiayari/akhbar/src/Header.tsx +191 -0
  70. package/template/community/hamdiayari/akhbar/src/Layout.tsx +49 -0
  71. package/template/community/hamdiayari/akhbar/src/Social.tsx +33 -0
  72. package/template/community/hamdiayari/akhbar/src/Ticker.tsx +86 -0
  73. package/template/community/hamdiayari/akhbar/src/Views.tsx +285 -0
  74. package/template/community/hamdiayari/akhbar/src/blocks/CollectionBlocks.tsx +672 -0
  75. package/template/community/hamdiayari/akhbar/src/blocks/ContentBlocks.tsx +305 -0
  76. package/template/community/hamdiayari/akhbar/src/blocks/ConversionBlocks.tsx +569 -0
  77. package/template/community/hamdiayari/akhbar/src/blocks/HeaderBlocks.tsx +287 -0
  78. package/template/community/hamdiayari/akhbar/src/index.tsx +51 -0
  79. package/template/community/hamdiayari/akhbar/src/kit.tsx +357 -0
  80. package/template/community/hamdiayari/akhbar/src/site.ts +96 -0
  81. package/template/community/hamdiayari/akhbar/src/styles.css +566 -0
  82. package/template/community/hamdiayari/akhbar-actualites/README.md +28 -0
  83. package/template/community/hamdiayari/akhbar-actualites/screenshot.jpg +0 -0
  84. package/template/community/hamdiayari/akhbar-actualites/snapify.module.json +107 -0
  85. package/template/community/hamdiayari/akhbar-actualites/src/admin/AudiencePage.tsx +185 -0
  86. package/template/community/hamdiayari/akhbar-actualites/src/admin/index.tsx +11 -0
  87. package/template/community/hamdiayari/akhbar-actualites/src/public/Archive.tsx +142 -0
  88. package/template/community/hamdiayari/akhbar-actualites/src/public/cards.tsx +152 -0
  89. package/template/community/hamdiayari/akhbar-actualites/src/public/index.tsx +71 -0
  90. package/template/community/hamdiayari/akhbar-actualites/src/public/posts.ts +103 -0
  91. package/template/community/hamdiayari/akhbar-actualites/src/public/styles.css +568 -0
  92. package/template/community/hamdiayari/akhbar-actualites/src/public/widgets.tsx +226 -0
  93. package/template/community/hamdiayari/akhbar-actualites/src/server.ts +119 -0
  94. package/template/community/hamdiayari/akhbar-actualites/src/types.ts +25 -0
  95. package/template/community/hamdiayari/akhbar-urgent/README.md +36 -0
  96. package/template/community/hamdiayari/akhbar-urgent/screenshot.jpg +0 -0
  97. package/template/community/hamdiayari/akhbar-urgent/snapify.module.json +64 -0
  98. package/template/community/hamdiayari/akhbar-urgent/src/admin/FlashesPage.tsx +229 -0
  99. package/template/community/hamdiayari/akhbar-urgent/src/admin/index.tsx +11 -0
  100. package/template/community/hamdiayari/akhbar-urgent/src/public/Ticker.tsx +81 -0
  101. package/template/community/hamdiayari/akhbar-urgent/src/public/index.tsx +63 -0
  102. package/template/community/hamdiayari/akhbar-urgent/src/public/styles.css +142 -0
  103. package/template/community/hamdiayari/akhbar-urgent/src/server.ts +101 -0
  104. package/template/community/hamdiayari/akhbar-urgent/src/types.ts +35 -0
  105. package/template/community.html +21 -0
  106. package/template/developers.html +24 -0
  107. package/template/docker-compose.db.yml +24 -0
  108. package/template/docs/BACKOFFICE_SNAPIFY.md +130 -0
  109. package/template/docs/CI_CD.md +66 -0
  110. package/template/docs/MODULES.md +346 -0
  111. package/template/docs/PLATFORM_DEPLOY.md +54 -0
  112. package/template/docs/logo.svg +10 -0
  113. package/template/drizzle/0000_init.sql +147 -0
  114. package/template/drizzle/0001_page_project.sql +5 -0
  115. package/template/drizzle/0002_modules.sql +23 -0
  116. package/template/drizzle/0003_themes.sql +4 -0
  117. package/template/drizzle/0004_security.sql +82 -0
  118. package/template/drizzle/0005_module_records.sql +16 -0
  119. package/template/drizzle/0006_avatars.sql +4 -0
  120. package/template/drizzle/0007_platform.sql +264 -0
  121. package/template/drizzle/0008_mp_validation.sql +3 -0
  122. package/template/drizzle/0009_saas_ops.sql +77 -0
  123. package/template/drizzle/0010_cms_chrome.sql +13 -0
  124. package/template/drizzle/0011_client_portal.sql +26 -0
  125. package/template/drizzle/meta/0000_snapshot.json +998 -0
  126. package/template/drizzle/meta/0001_snapshot.json +1004 -0
  127. package/template/drizzle/meta/_journal.json +90 -0
  128. package/template/drizzle.config.ts +16 -0
  129. package/template/ecosystem.snapify.cjs +24 -0
  130. package/template/for.html +1 -0
  131. package/template/index.html +29 -0
  132. package/template/landing.html +37 -0
  133. package/template/marketplace/catalog.json +373 -0
  134. package/template/marketplace/gallery/hamdiayari.preveris/01-home.jpg +0 -0
  135. package/template/marketplace/gallery/hamdiayari.recaptcha/01-reglages.jpg +0 -0
  136. package/template/marketplace/gallery/hamdiayari.recaptcha/02-logo.jpg +0 -0
  137. package/template/marketplace/gallery/novalabs.ai-articles/01-generer.jpg +0 -0
  138. package/template/marketplace/gallery/novalabs.ai-articles/02-fournisseur-ia.jpg +0 -0
  139. package/template/marketplace/gallery/novalabs.calendar/01-agenda-site.jpg +0 -0
  140. package/template/marketplace/gallery/novalabs.calendar/02-evenements-admin.jpg +0 -0
  141. package/template/marketplace/gallery/novalabs.calendar/03-reglages.jpg +0 -0
  142. package/template/marketplace/screenshots/hamdiayari.preveris-1.0.6.jpg +0 -0
  143. package/template/marketplace/screenshots/hamdiayari.recaptcha-1.0.0.jpg +0 -0
  144. package/template/marketplace/screenshots/hamdiayari.wp-seo-migrator-1.1.1.jpg +0 -0
  145. package/template/marketplace/screenshots/novalabs.ai-articles-1.0.1.jpg +0 -0
  146. package/template/marketplace/screenshots/novalabs.ai-chat-1.0.1.jpg +0 -0
  147. package/template/marketplace/screenshots/novalabs.calendar-1.0.1.jpg +0 -0
  148. package/template/marketplace/screenshots/novalabs.cart-1.0.0.jpg +0 -0
  149. package/template/marketplace/screenshots/novalabs.checkout-1.0.0.jpg +0 -0
  150. package/template/marketplace/screenshots/novalabs.customers-1.1.0.jpg +0 -0
  151. package/template/marketplace/screenshots/novalabs.dogga-1.0.0.jpg +0 -0
  152. package/template/marketplace/screenshots/novalabs.mahdia-1.0.0.jpg +0 -0
  153. package/template/marketplace/screenshots/novalabs.shop-1.0.0.jpg +0 -0
  154. package/template/marketplace/screenshots/novalabs.sidibou-1.0.0.jpg +0 -0
  155. package/template/marketplace/screenshots/novalabs.whatsapp-1.0.1.jpg +0 -0
  156. package/template/marketplace.html +21 -0
  157. package/template/metadata.json +7 -0
  158. package/template/modules/ai-articles/screenshot.jpg +0 -0
  159. package/template/modules/ai-articles/snapify.module.json +74 -0
  160. package/template/modules/ai-articles/src/admin/ArticlesPage.tsx +162 -0
  161. package/template/modules/ai-articles/src/admin/GeneratePage.tsx +118 -0
  162. package/template/modules/ai-articles/src/admin/index.tsx +12 -0
  163. package/template/modules/ai-articles/src/public/index.tsx +119 -0
  164. package/template/modules/ai-articles/src/server.ts +287 -0
  165. package/template/modules/ai-articles/src/types.ts +30 -0
  166. package/template/modules/ai-chat/screenshot.jpg +0 -0
  167. package/template/modules/ai-chat/snapify.module.json +217 -0
  168. package/template/modules/ai-chat/src/public.tsx +198 -0
  169. package/template/modules/ai-chat/src/server.ts +142 -0
  170. package/template/modules/ai-theme-studio/README.md +15 -0
  171. package/template/modules/ai-theme-studio/screenshot.jpg +0 -0
  172. package/template/modules/ai-theme-studio/snapify.module.json +175 -0
  173. package/template/modules/ai-theme-studio/src/admin/HistoryPage.tsx +91 -0
  174. package/template/modules/ai-theme-studio/src/admin/StudioPage.tsx +414 -0
  175. package/template/modules/ai-theme-studio/src/admin/index.tsx +11 -0
  176. package/template/modules/ai-theme-studio/src/lib/images.ts +240 -0
  177. package/template/modules/ai-theme-studio/src/lib/llm.ts +123 -0
  178. package/template/modules/ai-theme-studio/src/lib/normalize.ts +714 -0
  179. package/template/modules/ai-theme-studio/src/lib/prompts.ts +198 -0
  180. package/template/modules/ai-theme-studio/src/server.ts +137 -0
  181. package/template/modules/ai-theme-studio/src/types.ts +112 -0
  182. package/template/modules/calendar/screenshot.jpg +0 -0
  183. package/template/modules/calendar/snapify.module.json +45 -0
  184. package/template/modules/calendar/src/admin/EventsPage.tsx +217 -0
  185. package/template/modules/calendar/src/admin/index.tsx +11 -0
  186. package/template/modules/calendar/src/public/index.tsx +231 -0
  187. package/template/modules/calendar/src/server.ts +143 -0
  188. package/template/modules/calendar/src/types.ts +25 -0
  189. package/template/modules/cart/screenshot.jpg +0 -0
  190. package/template/modules/cart/snapify.module.json +90 -0
  191. package/template/modules/cart/src/admin/index.tsx +265 -0
  192. package/template/modules/cart/src/public/CartPage.tsx +198 -0
  193. package/template/modules/cart/src/public/index.tsx +261 -0
  194. package/template/modules/cart/src/public/useQuote.ts +67 -0
  195. package/template/modules/cart/src/server.ts +148 -0
  196. package/template/modules/cart/src/types.ts +31 -0
  197. package/template/modules/checkout/screenshot.jpg +0 -0
  198. package/template/modules/checkout/snapify.module.json +264 -0
  199. package/template/modules/checkout/src/admin/OrderDetailPage.tsx +304 -0
  200. package/template/modules/checkout/src/admin/badges.tsx +28 -0
  201. package/template/modules/checkout/src/admin/index.tsx +236 -0
  202. package/template/modules/checkout/src/public/CheckoutPage.tsx +461 -0
  203. package/template/modules/checkout/src/public/OrderPages.tsx +153 -0
  204. package/template/modules/checkout/src/public/index.tsx +23 -0
  205. package/template/modules/checkout/src/server.ts +383 -0
  206. package/template/modules/checkout/src/types.ts +70 -0
  207. package/template/modules/customers/screenshot.jpg +0 -0
  208. package/template/modules/customers/snapify.module.json +115 -0
  209. package/template/modules/customers/src/admin/CustomerDetailPage.tsx +274 -0
  210. package/template/modules/customers/src/admin/index.tsx +194 -0
  211. package/template/modules/customers/src/public/AccountPages.tsx +470 -0
  212. package/template/modules/customers/src/public/AddressForm.tsx +115 -0
  213. package/template/modules/customers/src/public/AuthPages.tsx +349 -0
  214. package/template/modules/customers/src/public/Avatar.tsx +29 -0
  215. package/template/modules/customers/src/public/ProfileSection.tsx +291 -0
  216. package/template/modules/customers/src/public/index.tsx +137 -0
  217. package/template/modules/customers/src/public/session.ts +51 -0
  218. package/template/modules/customers/src/server.ts +421 -0
  219. package/template/modules/customers/src/types.ts +53 -0
  220. package/template/modules/recaptcha/logo.jpg +0 -0
  221. package/template/modules/recaptcha/screenshot.jpg +0 -0
  222. package/template/modules/recaptcha/snapify.module.json +99 -0
  223. package/template/modules/recaptcha/src/public/index.tsx +94 -0
  224. package/template/modules/recaptcha/src/server.ts +65 -0
  225. package/template/modules/recaptcha/src/types.ts +18 -0
  226. package/template/modules/shop/screenshot.jpg +0 -0
  227. package/template/modules/shop/snapify.module.json +340 -0
  228. package/template/modules/shop/src/admin/CategoriesPage.tsx +224 -0
  229. package/template/modules/shop/src/admin/ProductEditor.tsx +313 -0
  230. package/template/modules/shop/src/admin/ProductsPage.tsx +307 -0
  231. package/template/modules/shop/src/admin/index.tsx +14 -0
  232. package/template/modules/shop/src/public/Catalog.tsx +244 -0
  233. package/template/modules/shop/src/public/NotFound.tsx +22 -0
  234. package/template/modules/shop/src/public/ProductPage.tsx +195 -0
  235. package/template/modules/shop/src/public/index.tsx +134 -0
  236. package/template/modules/shop/src/public/useFetch.ts +26 -0
  237. package/template/modules/shop/src/server.ts +493 -0
  238. package/template/modules/shop/src/shared.ts +41 -0
  239. package/template/modules/shop/src/types.ts +60 -0
  240. package/template/modules/whatsapp/screenshot.jpg +0 -0
  241. package/template/modules/whatsapp/snapify.module.json +121 -0
  242. package/template/modules/whatsapp/src/public.tsx +119 -0
  243. package/template/modules/wp-seo-migrator/ARCHITECTURE.md +113 -0
  244. package/template/modules/wp-seo-migrator/README.md +21 -0
  245. package/template/modules/wp-seo-migrator/fixtures/aioseo-sample.csv +3 -0
  246. package/template/modules/wp-seo-migrator/fixtures/sample-exporter.json +39 -0
  247. package/template/modules/wp-seo-migrator/fixtures/sample-page.html +12 -0
  248. package/template/modules/wp-seo-migrator/fixtures/sample.htaccess +3 -0
  249. package/template/modules/wp-seo-migrator/screenshot.jpg +0 -0
  250. package/template/modules/wp-seo-migrator/snapify.module.json +87 -0
  251. package/template/modules/wp-seo-migrator/src/admin/HistoryPage.tsx +64 -0
  252. package/template/modules/wp-seo-migrator/src/admin/WizardPage.tsx +788 -0
  253. package/template/modules/wp-seo-migrator/src/admin/i18n.ts +156 -0
  254. package/template/modules/wp-seo-migrator/src/admin/index.tsx +11 -0
  255. package/template/modules/wp-seo-migrator/src/connectors/CUSTOM_CONNECTOR.md +31 -0
  256. package/template/modules/wp-seo-migrator/src/connectors/csvSeoFactory.ts +106 -0
  257. package/template/modules/wp-seo-migrator/src/connectors/exporter.ts +96 -0
  258. package/template/modules/wp-seo-migrator/src/connectors/gscCsv.ts +53 -0
  259. package/template/modules/wp-seo-migrator/src/connectors/htaccess.ts +65 -0
  260. package/template/modules/wp-seo-migrator/src/connectors/htmlCrawler.ts +90 -0
  261. package/template/modules/wp-seo-migrator/src/connectors/index.ts +113 -0
  262. package/template/modules/wp-seo-migrator/src/connectors/pluginCsv.ts +77 -0
  263. package/template/modules/wp-seo-migrator/src/connectors/rankMathCsv.ts +77 -0
  264. package/template/modules/wp-seo-migrator/src/connectors/redirection.ts +62 -0
  265. package/template/modules/wp-seo-migrator/src/connectors/sitemap.ts +44 -0
  266. package/template/modules/wp-seo-migrator/src/connectors/utils.ts +111 -0
  267. package/template/modules/wp-seo-migrator/src/connectors/wxr.ts +103 -0
  268. package/template/modules/wp-seo-migrator/src/connectors/yoastCsv.ts +56 -0
  269. package/template/modules/wp-seo-migrator/src/pipeline/analyze.ts +158 -0
  270. package/template/modules/wp-seo-migrator/src/pipeline/htmlParse.ts +58 -0
  271. package/template/modules/wp-seo-migrator/src/pipeline/remoteAuto.ts +328 -0
  272. package/template/modules/wp-seo-migrator/src/server.ts +492 -0
  273. package/template/modules/wp-seo-migrator/src/types.ts +151 -0
  274. package/template/modules/wp-seo-migrator/tests/connectors-extra.test.ts +39 -0
  275. package/template/modules/wp-seo-migrator/tests/merge.test.ts +25 -0
  276. package/template/package-lock.json +6016 -0
  277. package/template/package.json +74 -0
  278. package/template/public/images/photos/caravane-chameaux-desert.webp +0 -0
  279. package/template/public/images/photos/hammamet-medina-plage.jpg +0 -0
  280. package/template/public/images/photos/maison-campagne-collines.webp +0 -0
  281. package/template/public/images/photos/maisons-troglodytes-desert.jpg +0 -0
  282. package/template/public/images/photos/panorama-ville.jpg +0 -0
  283. package/template/public/images/photos/preveris-accessibilite-erp.jpg +0 -0
  284. package/template/public/images/photos/preveris-collectivites.jpg +0 -0
  285. package/template/public/images/photos/preveris-etudes-plans.jpg +0 -0
  286. package/template/public/images/photos/preveris-hero-erp.jpg +0 -0
  287. package/template/public/images/photos/preveris-ssi-incendie.jpg +0 -0
  288. package/template/public/images/photos/preveris-suivi-hotel.jpg +0 -0
  289. package/template/public/images/photos/ruelle-bleue-medina.jpg +0 -0
  290. package/template/public/images/photos/sidi-bou-said-port.webp +0 -0
  291. package/template/public/images/photos/terrasse-blanche-mer-voilier.jpg +0 -0
  292. package/template/public/landing/hero-ai-cms.jpg +0 -0
  293. package/template/public/landing/shot-dogga.jpg +0 -0
  294. package/template/public/landing/shot-mahdia.jpg +0 -0
  295. package/template/public/landing/shot-sidibou.jpg +0 -0
  296. package/template/public/llms.txt +35 -0
  297. package/template/public/logo.svg +10 -0
  298. package/template/scripts/app-pack.ts +155 -0
  299. package/template/scripts/app-publish.ts +100 -0
  300. package/template/scripts/apply-ecommerce-home.ts +196 -0
  301. package/template/scripts/auto-deploy-poll.sh +13 -0
  302. package/template/scripts/db-backup.sh +16 -0
  303. package/template/scripts/db-restore.sh +11 -0
  304. package/template/scripts/deploy.sh +34 -0
  305. package/template/scripts/github-webhook-deploy.sh +7 -0
  306. package/template/scripts/install-new-modules.ts +96 -0
  307. package/template/scripts/refresh-demo-baseline.ts +9 -0
  308. package/template/scripts/reinstall-marketplace-packs.ts +51 -0
  309. package/template/scripts/restore-classic-home.ts +13 -0
  310. package/template/scripts/sdk-pack.ts +289 -0
  311. package/template/scripts/sdk-publish.ts +75 -0
  312. package/template/scripts/seed-demo-products.ts +120 -0
  313. package/template/scripts/seed-theme-content-packs.ts +42 -0
  314. package/template/scripts/snapify-module.ts +207 -0
  315. package/template/scripts/test-theme-switch.ts +24 -0
  316. package/template/sdk/admin.css +18 -0
  317. package/template/sdk/admin.ts +95 -0
  318. package/template/sdk/build.ts +249 -0
  319. package/template/sdk/commerce.ts +512 -0
  320. package/template/sdk/content.ts +76 -0
  321. package/template/sdk/icons.ts +101 -0
  322. package/template/sdk/image.ts +60 -0
  323. package/template/sdk/index.ts +500 -0
  324. package/template/sdk/package.ts +298 -0
  325. package/template/sdk/recaptcha.tsx +122 -0
  326. package/template/sdk/settings.ts +84 -0
  327. package/template/sdk/theme.css +29 -0
  328. package/template/sdk/theme.ts +100 -0
  329. package/template/sdk/ui/commerce.tsx +385 -0
  330. package/template/sdk/ui/orders.tsx +136 -0
  331. package/template/sdk-kit/CHANGELOG.md +17 -0
  332. package/template/sdk-kit/LICENSE.md +47 -0
  333. package/template/sdk-kit/README.md +81 -0
  334. package/template/sdk-kit/cli.ts +339 -0
  335. package/template/sdk-kit/create-snapify/README.md +28 -0
  336. package/template/sdk-kit/create-snapify/create-snapify.mjs +11 -0
  337. package/template/sdk-kit/create-snapify/package.template.json +16 -0
  338. package/template/sdk-kit/package.template.json +95 -0
  339. package/template/sdk-kit/templates/common/README.md.tpl +27 -0
  340. package/template/sdk-kit/templates/common/_gitignore +3 -0
  341. package/template/sdk-kit/templates/common/package.json.tpl +19 -0
  342. package/template/sdk-kit/templates/common/src/snapify-env.d.ts +2 -0
  343. package/template/sdk-kit/templates/common/tsconfig.json +15 -0
  344. package/template/sdk-kit/templates/module/snapify.module.json.tpl +33 -0
  345. package/template/sdk-kit/templates/module/src/admin.tsx +53 -0
  346. package/template/sdk-kit/templates/module/src/public.tsx +49 -0
  347. package/template/sdk-kit/templates/module/src/server.ts +30 -0
  348. package/template/sdk-kit/templates/module/src/types.ts +19 -0
  349. package/template/sdk-kit/templates/theme/snapify.theme.json.tpl +22 -0
  350. package/template/sdk-kit/templates/theme/src/Footer.tsx +40 -0
  351. package/template/sdk-kit/templates/theme/src/Header.tsx +47 -0
  352. package/template/sdk-kit/templates/theme/src/Views.tsx +36 -0
  353. package/template/sdk-kit/templates/theme/src/blocks.tsx +93 -0
  354. package/template/sdk-kit/templates/theme/src/index.tsx +30 -0
  355. package/template/sdk-kit/templates/theme/src/site.tsx +59 -0
  356. package/template/sdk-kit/templates/theme/src/styles.css +71 -0
  357. package/template/server/client/routes.ts +252 -0
  358. package/template/server/cms/analyticsStore.ts +180 -0
  359. package/template/server/cms/auth.ts +155 -0
  360. package/template/server/cms/blockCatalog.ts +342 -0
  361. package/template/server/cms/blocks.ts +521 -0
  362. package/template/server/cms/contentMigration.ts +1119 -0
  363. package/template/server/cms/defaults.ts +303 -0
  364. package/template/server/cms/permissions.ts +154 -0
  365. package/template/server/cms/restoreClassicHome.ts +183 -0
  366. package/template/server/cms/revisions.ts +99 -0
  367. package/template/server/cms/scheduler.ts +78 -0
  368. package/template/server/cms/seed.ts +72 -0
  369. package/template/server/cms/seoAnalyzer.ts +213 -0
  370. package/template/server/cms/store.ts +122 -0
  371. package/template/server/cms/themeContent.ts +1386 -0
  372. package/template/server/cms/themePacks/sidibou-branding.json +1 -0
  373. package/template/server/cms/themePacks/sidibou-home.json +1 -0
  374. package/template/server/cms/themePacks/sidibou-menus.json +1 -0
  375. package/template/server/cms/types.ts +432 -0
  376. package/template/server/community/routes.ts +410 -0
  377. package/template/server/db/client.ts +43 -0
  378. package/template/server/db/repository.ts +389 -0
  379. package/template/server/db/schema.ts +726 -0
  380. package/template/server/demo/cmsReset.ts +196 -0
  381. package/template/server/developers/sdk.ts +85 -0
  382. package/template/server/geoip.ts +15 -0
  383. package/template/server/http.ts +53 -0
  384. package/template/server/mail.ts +216 -0
  385. package/template/server/marketplace/catalog.ts +74 -0
  386. package/template/server/marketplace/packageValidate.ts +475 -0
  387. package/template/server/marketplace/payments.ts +193 -0
  388. package/template/server/marketplace/routes.ts +850 -0
  389. package/template/server/marketplace/signing.ts +116 -0
  390. package/template/server/marketplace/syncOfficial.ts +282 -0
  391. package/template/server/media/images.ts +63 -0
  392. package/template/server/middleware/adminAuth.ts +134 -0
  393. package/template/server/modules/legacy.ts +44 -0
  394. package/template/server/modules/manager.ts +1122 -0
  395. package/template/server/modules/marketplace.ts +178 -0
  396. package/template/server/modules/outbound.ts +178 -0
  397. package/template/server/modules/purchases.ts +149 -0
  398. package/template/server/modules/records.ts +168 -0
  399. package/template/server/modules/themeHtml.ts +32 -0
  400. package/template/server/modules/trust.ts +16 -0
  401. package/template/server/modules/types.ts +147 -0
  402. package/template/server/platform/auth.ts +223 -0
  403. package/template/server/platform/clientWelcome.ts +168 -0
  404. package/template/server/platform/clients.ts +139 -0
  405. package/template/server/platform/dailyImprove.ts +356 -0
  406. package/template/server/platform/flouci.ts +126 -0
  407. package/template/server/platform/host.ts +69 -0
  408. package/template/server/platform/hostingProviders.ts +143 -0
  409. package/template/server/platform/licenseOrders.ts +291 -0
  410. package/template/server/platform/money.ts +42 -0
  411. package/template/server/platform/passwords.ts +41 -0
  412. package/template/server/platform/region.ts +86 -0
  413. package/template/server/platform/routes.ts +225 -0
  414. package/template/server/platform/seed.ts +82 -0
  415. package/template/server/platform/settings.ts +72 -0
  416. package/template/server/routes/adminAccount.ts +403 -0
  417. package/template/server/routes/adminCms.ts +808 -0
  418. package/template/server/routes/adminSystem.ts +243 -0
  419. package/template/server/routes/adminUsers.ts +449 -0
  420. package/template/server/routes/googleOAuth.ts +327 -0
  421. package/template/server/routes/modules.ts +323 -0
  422. package/template/server/routes/publicCms.ts +313 -0
  423. package/template/server/routes/seoPublic.ts +158 -0
  424. package/template/server/security/accounts.ts +121 -0
  425. package/template/server/security/audit.ts +143 -0
  426. package/template/server/security/authTokens.ts +74 -0
  427. package/template/server/security/ip.ts +68 -0
  428. package/template/server/security/rateLimit.ts +85 -0
  429. package/template/server/security/retention.ts +46 -0
  430. package/template/server/security/secrets.ts +44 -0
  431. package/template/server/security/sessions.ts +140 -0
  432. package/template/server/security/totp.ts +101 -0
  433. package/template/server/superadmin/analytics.ts +109 -0
  434. package/template/server/superadmin/auth.ts +92 -0
  435. package/template/server/superadmin/backlinksCatalog.ts +210 -0
  436. package/template/server/superadmin/frSeoContent.ts +165 -0
  437. package/template/server/superadmin/landingSeo.ts +675 -0
  438. package/template/server/superadmin/ops.ts +238 -0
  439. package/template/server/superadmin/routes.ts +1095 -0
  440. package/template/server/superadmin/tnSeoContent.ts +130 -0
  441. package/template/server.ts +522 -0
  442. package/template/src/App.tsx +263 -0
  443. package/template/src/admin/AdminApp.tsx +162 -0
  444. package/template/src/admin/account/AuthLayout.tsx +57 -0
  445. package/template/src/admin/account/SecurityForms.tsx +276 -0
  446. package/template/src/admin/admin.css +127 -0
  447. package/template/src/admin/context/AuthContext.tsx +147 -0
  448. package/template/src/admin/context/SiteContext.tsx +50 -0
  449. package/template/src/admin/editor/BlockLibrary.tsx +173 -0
  450. package/template/src/admin/editor/BlocksPanel.tsx +396 -0
  451. package/template/src/admin/editor/EditorBits.tsx +106 -0
  452. package/template/src/admin/editor/PreviewFrame.tsx +145 -0
  453. package/template/src/admin/editor/RichTextEditor.tsx +276 -0
  454. package/template/src/admin/editor/SeoPanel.tsx +349 -0
  455. package/template/src/admin/editor/StyleEditor.tsx +114 -0
  456. package/template/src/admin/editor/blockSchemas.ts +699 -0
  457. package/template/src/admin/editor/fields.tsx +486 -0
  458. package/template/src/admin/layout/AdminShell.tsx +418 -0
  459. package/template/src/admin/layout/nav.ts +95 -0
  460. package/template/src/admin/lib/api.ts +408 -0
  461. package/template/src/admin/lib/audit.ts +141 -0
  462. package/template/src/admin/lib/format.ts +84 -0
  463. package/template/src/admin/lib/hooks.ts +125 -0
  464. package/template/src/admin/main.tsx +16 -0
  465. package/template/src/admin/modules/InstallDialog.tsx +160 -0
  466. package/template/src/admin/modules/SettingsForm.tsx +145 -0
  467. package/template/src/admin/modules/kit.tsx +127 -0
  468. package/template/src/admin/modules/labels.tsx +226 -0
  469. package/template/src/admin/pages/AccountSetupPage.tsx +62 -0
  470. package/template/src/admin/pages/AnalyticsPage.tsx +206 -0
  471. package/template/src/admin/pages/BrandingPage.tsx +154 -0
  472. package/template/src/admin/pages/DashboardPage.tsx +239 -0
  473. package/template/src/admin/pages/EngagementPage.tsx +168 -0
  474. package/template/src/admin/pages/FormsPage.tsx +435 -0
  475. package/template/src/admin/pages/GeneralPage.tsx +120 -0
  476. package/template/src/admin/pages/LoginPage.tsx +249 -0
  477. package/template/src/admin/pages/MaintenancePage.tsx +125 -0
  478. package/template/src/admin/pages/MarketplacePage.tsx +426 -0
  479. package/template/src/admin/pages/MediaPage.tsx +251 -0
  480. package/template/src/admin/pages/MenusPage.tsx +446 -0
  481. package/template/src/admin/pages/ModuleAdminPage.tsx +113 -0
  482. package/template/src/admin/pages/ModuleDetailPage.tsx +293 -0
  483. package/template/src/admin/pages/ModulesPage.tsx +135 -0
  484. package/template/src/admin/pages/NewsletterPage.tsx +193 -0
  485. package/template/src/admin/pages/PageEditorPage.tsx +322 -0
  486. package/template/src/admin/pages/PagesListPage.tsx +277 -0
  487. package/template/src/admin/pages/PostEditorPage.tsx +292 -0
  488. package/template/src/admin/pages/PostsListPage.tsx +187 -0
  489. package/template/src/admin/pages/ProfilePage.tsx +489 -0
  490. package/template/src/admin/pages/ResetPasswordPage.tsx +110 -0
  491. package/template/src/admin/pages/SeoPage.tsx +670 -0
  492. package/template/src/admin/pages/SettingsPage.tsx +189 -0
  493. package/template/src/admin/pages/ThemeCustomizePage.tsx +170 -0
  494. package/template/src/admin/pages/ThemesPage.tsx +292 -0
  495. package/template/src/admin/pages/UsersPage.tsx +57 -0
  496. package/template/src/admin/pages/WidgetsPage.tsx +200 -0
  497. package/template/src/admin/seo/GoogleSetup.tsx +529 -0
  498. package/template/src/admin/settings/EmailTab.tsx +293 -0
  499. package/template/src/admin/settings/OtherTabs.tsx +270 -0
  500. package/template/src/admin/settings/SecurityTab.tsx +172 -0
  501. package/template/src/admin/settings/controls.tsx +133 -0
  502. package/template/src/admin/ui/Pagination.tsx +170 -0
  503. package/template/src/admin/ui/SaveBar.tsx +77 -0
  504. package/template/src/admin/ui/TagInput.tsx +54 -0
  505. package/template/src/admin/ui/charts.tsx +108 -0
  506. package/template/src/admin/ui/media.tsx +265 -0
  507. package/template/src/admin/ui/overlays.tsx +239 -0
  508. package/template/src/admin/ui/primitives.tsx +544 -0
  509. package/template/src/admin/users/AuditTab.tsx +104 -0
  510. package/template/src/admin/users/RolesTab.tsx +368 -0
  511. package/template/src/admin/users/UsersTab.tsx +723 -0
  512. package/template/src/admin/users/shared.tsx +278 -0
  513. package/template/src/cms/icons.ts +7 -0
  514. package/template/src/components/CookieBanner.tsx +166 -0
  515. package/template/src/components/MaintenanceGate.tsx +66 -0
  516. package/template/src/components/SiteAnalytics.tsx +64 -0
  517. package/template/src/components/SnapifyLogo.tsx +44 -0
  518. package/template/src/components/cms/BlockRenderer.tsx +154 -0
  519. package/template/src/components/cms/WidgetArea.tsx +193 -0
  520. package/template/src/context/SiteConfigContext.tsx +130 -0
  521. package/template/src/demoBase.ts +23 -0
  522. package/template/src/index.css +90 -0
  523. package/template/src/main.tsx +16 -0
  524. package/template/src/modules/ModuleHost.tsx +197 -0
  525. package/template/src/preview.ts +63 -0
  526. package/template/src/runtime.ts +38 -0
  527. package/template/src/themes/ThemeHost.tsx +168 -0
  528. package/template/src/themes/fallback.tsx +71 -0
  529. package/template/src/types.ts +94 -0
  530. package/template/src/views/BlogPostView.tsx +68 -0
  531. package/template/src/views/CmsPageView.tsx +34 -0
  532. package/template/start-pm2.sh +3 -0
  533. package/template/superadmin.html +20 -0
  534. package/template/themes/ai-canvas/screenshot.jpg +0 -0
  535. package/template/themes/ai-canvas/snapify.theme.json +96 -0
  536. package/template/themes/ai-canvas/src/CeeSimulator.tsx +247 -0
  537. package/template/themes/ai-canvas/src/Footer.tsx +190 -0
  538. package/template/themes/ai-canvas/src/Header.tsx +324 -0
  539. package/template/themes/ai-canvas/src/Layout.tsx +56 -0
  540. package/template/themes/ai-canvas/src/NotFound.tsx +58 -0
  541. package/template/themes/ai-canvas/src/Post.tsx +26 -0
  542. package/template/themes/ai-canvas/src/SnapifyLogo.tsx +44 -0
  543. package/template/themes/ai-canvas/src/blocks/CollectionBlocks.tsx +711 -0
  544. package/template/themes/ai-canvas/src/blocks/ContentBlocks.tsx +318 -0
  545. package/template/themes/ai-canvas/src/blocks/ConversionBlocks.tsx +559 -0
  546. package/template/themes/ai-canvas/src/blocks/HeaderBlocks.tsx +341 -0
  547. package/template/themes/ai-canvas/src/index.tsx +54 -0
  548. package/template/themes/ai-canvas/src/kit.tsx +398 -0
  549. package/template/themes/ai-canvas/src/site.ts +29 -0
  550. package/template/themes/ai-canvas/src/styles.css +317 -0
  551. package/template/themes/dogga/screenshot.jpg +0 -0
  552. package/template/themes/dogga/snapify.theme.json +55 -0
  553. package/template/themes/dogga/src/Brand.tsx +41 -0
  554. package/template/themes/dogga/src/Footer.tsx +202 -0
  555. package/template/themes/dogga/src/Header.tsx +239 -0
  556. package/template/themes/dogga/src/Layout.tsx +43 -0
  557. package/template/themes/dogga/src/Views.tsx +71 -0
  558. package/template/themes/dogga/src/blocks/CollectionBlocks.tsx +674 -0
  559. package/template/themes/dogga/src/blocks/ContentBlocks.tsx +307 -0
  560. package/template/themes/dogga/src/blocks/ConversionBlocks.tsx +571 -0
  561. package/template/themes/dogga/src/blocks/HeaderBlocks.tsx +289 -0
  562. package/template/themes/dogga/src/index.tsx +53 -0
  563. package/template/themes/dogga/src/kit.tsx +362 -0
  564. package/template/themes/dogga/src/site.ts +56 -0
  565. package/template/themes/dogga/src/styles.css +396 -0
  566. package/template/themes/mahdia/screenshot.jpg +0 -0
  567. package/template/themes/mahdia/snapify.theme.json +65 -0
  568. package/template/themes/mahdia/src/Brand.tsx +39 -0
  569. package/template/themes/mahdia/src/Footer.tsx +210 -0
  570. package/template/themes/mahdia/src/Header.tsx +291 -0
  571. package/template/themes/mahdia/src/Layout.tsx +44 -0
  572. package/template/themes/mahdia/src/Views.tsx +79 -0
  573. package/template/themes/mahdia/src/blocks/CollectionBlocks.tsx +674 -0
  574. package/template/themes/mahdia/src/blocks/ContentBlocks.tsx +307 -0
  575. package/template/themes/mahdia/src/blocks/ConversionBlocks.tsx +571 -0
  576. package/template/themes/mahdia/src/blocks/HeaderBlocks.tsx +289 -0
  577. package/template/themes/mahdia/src/index.tsx +53 -0
  578. package/template/themes/mahdia/src/kit.tsx +362 -0
  579. package/template/themes/mahdia/src/site.ts +75 -0
  580. package/template/themes/mahdia/src/styles.css +446 -0
  581. package/template/themes/preveris/screenshot.jpg +0 -0
  582. package/template/themes/preveris/snapify.theme.json +126 -0
  583. package/template/themes/preveris/src/Brand.tsx +44 -0
  584. package/template/themes/preveris/src/Footer.tsx +202 -0
  585. package/template/themes/preveris/src/Header.tsx +239 -0
  586. package/template/themes/preveris/src/Layout.tsx +42 -0
  587. package/template/themes/preveris/src/Views.tsx +71 -0
  588. package/template/themes/preveris/src/blocks/CollectionBlocks.tsx +678 -0
  589. package/template/themes/preveris/src/blocks/ContentBlocks.tsx +307 -0
  590. package/template/themes/preveris/src/blocks/ConversionBlocks.tsx +571 -0
  591. package/template/themes/preveris/src/blocks/HeaderBlocks.tsx +299 -0
  592. package/template/themes/preveris/src/index.tsx +53 -0
  593. package/template/themes/preveris/src/kit.tsx +365 -0
  594. package/template/themes/preveris/src/site.ts +79 -0
  595. package/template/themes/preveris/src/styles.css +446 -0
  596. package/template/themes/sidibou/screenshot.jpg +0 -0
  597. package/template/themes/sidibou/snapify.theme.json +21 -0
  598. package/template/themes/sidibou/src/CeeSimulator.tsx +247 -0
  599. package/template/themes/sidibou/src/Footer.tsx +203 -0
  600. package/template/themes/sidibou/src/Header.tsx +324 -0
  601. package/template/themes/sidibou/src/Layout.tsx +53 -0
  602. package/template/themes/sidibou/src/NotFound.tsx +58 -0
  603. package/template/themes/sidibou/src/Post.tsx +26 -0
  604. package/template/themes/sidibou/src/SnapifyLogo.tsx +44 -0
  605. package/template/themes/sidibou/src/blocks/CollectionBlocks.tsx +711 -0
  606. package/template/themes/sidibou/src/blocks/ContentBlocks.tsx +318 -0
  607. package/template/themes/sidibou/src/blocks/ConversionBlocks.tsx +559 -0
  608. package/template/themes/sidibou/src/blocks/HeaderBlocks.tsx +341 -0
  609. package/template/themes/sidibou/src/index.tsx +54 -0
  610. package/template/themes/sidibou/src/kit.tsx +398 -0
  611. package/template/themes/sidibou/src/site.ts +28 -0
  612. package/template/themes/sidibou/src/styles.css +317 -0
  613. package/template/tsconfig.json +33 -0
  614. package/template/vite.config.ts +42 -0
@@ -0,0 +1,24 @@
1
+ <!doctype html>
2
+ <!--
3
+ Snapify Developers
4
+ © 2026 NOVALABS WEB DESIGN — Tunisie
5
+ -->
6
+ <html lang="fr">
7
+ <head>
8
+ <meta charset="UTF-8" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
+ <title>Snapify Developers — Créer des modules et des thèmes</title>
11
+ <meta name="description" content="Documentation officielle pour développer des modules et des thèmes Snapify : SDK, manifeste, API serveur, paquets signés et publication sur la marketplace." />
12
+ <meta property="og:title" content="Snapify Developers" />
13
+ <meta property="og:description" content="Créez des modules et des thèmes pour le CMS Snapify et publiez-les sur la marketplace." />
14
+ <meta property="og:type" content="website" />
15
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
16
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
17
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
18
+ <link rel="icon" type="image/svg+xml" href="/logo.svg" />
19
+ </head>
20
+ <body class="bg-white text-slate-900 antialiased">
21
+ <div id="root"></div>
22
+ <script type="module" src="/apps/developers/src/main.tsx"></script>
23
+ </body>
24
+ </html>
@@ -0,0 +1,24 @@
1
+ name: snapify
2
+
3
+ services:
4
+ postgres:
5
+ image: postgres:17-alpine
6
+ container_name: snapify-postgres
7
+ restart: unless-stopped
8
+ environment:
9
+ POSTGRES_DB: snapify
10
+ POSTGRES_USER: snapify
11
+ POSTGRES_PASSWORD: ${SNAPIFY_DB_PASSWORD:?SNAPIFY_DB_PASSWORD manquant}
12
+ TZ: Europe/Paris
13
+ ports:
14
+ - "127.0.0.1:${SNAPIFY_DB_PORT:-5433}:5432"
15
+ volumes:
16
+ - snapify_pgdata:/var/lib/postgresql/data
17
+ healthcheck:
18
+ test: ["CMD-SHELL", "pg_isready -U snapify -d snapify"]
19
+ interval: 10s
20
+ timeout: 5s
21
+ retries: 5
22
+
23
+ volumes:
24
+ snapify_pgdata:
@@ -0,0 +1,130 @@
1
+ # Backoffice Snapify — guide complet
2
+
3
+ ## Accès
4
+
5
+ | Élément | URL / chemin |
6
+ |---------|----------------|
7
+ | Backoffice | `/administrator` |
8
+ | API admin | `/api/admin/*` (JWT) |
9
+ | API publique | `/api/public/*` |
10
+ | Sitemap | `/sitemap.xml` |
11
+ | Robots | `/robots.txt` |
12
+ | Base de données | PostgreSQL 17 (`snapify-postgres`, `127.0.0.1:5433`) |
13
+ | Sauvegardes | `backups/db/*.dump` (quotidien 03:30, 14 jours) |
14
+ | Médias | `public/uploads/` |
15
+
16
+ Identifiants : `ADMIN_EMAIL` / `ADMIN_PASSWORD` (`.env`).
17
+
18
+ ## Fonctionnalités livrées (v2 — refonte complète, aucun JSON exposé)
19
+
20
+ - **Interface** : sidebar par rôle, palette de commandes `Ctrl+K`, bandeau maintenance, garde « modifications non enregistrées », toasts, mobile.
21
+ - **Tableau de bord / Statistiques** : visiteurs, sessions, durée moyenne, rebond, pays (drapeaux), sources, appareils, pages (temps moyen), export CSV, périodes 7/30/90/365 j.
22
+ - **Pages — constructeur visuel plein écran** : structure de la page à gauche (glisser-déposer, insertion entre deux blocs, duplication, masquage, suppression), inspecteur « Contenu » (tous les textes, boutons, images, vidéos, listes, icônes, tableaux) et « Style & animation » (fond blanc/gris/dégradé/sombre/marque/photo/vidéo + voile, motif décoratif, marges, largeur, animation d’apparition, ancre, masquage mobile/ordinateur), et **aperçu réel** du site à droite (ordinateur / tablette / mobile) mis à jour à chaque frappe. Cliquer un bloc dans l’aperçu l’ouvre dans l’inspecteur. Onglet « Page » : titre, statut, planification, adresse, modèle, fiche réalisation ; bouton « SEO » ; historique des versions.
23
+ - **25 blocs** (bibliothèque par catégorie avec recherche) : bannière d’accueil, en-tête de page, texte, texte + image / vidéo, sections + encadré, image, vidéo, diaporama, galerie, bandeau défilant, cartes (5 styles), vitrine à onglets, étapes, chiffres clés, panneaux extensibles, cartes de garanties, FAQ, témoignages, tableau, appel à l’action, réalisations (liste automatique), simulateur CEE, formulaire de contact, espace, code HTML.
24
+ - **Toutes les pages du site** (23, accueil comprise) sont composées de blocs stockés en base : aucun contenu de page n’est figé dans le code. Variables utilisables dans les textes : `{{telephone}}`, `{{email}}`, `{{delai}}`, `{{societe}}`, `{{annee}}`, `{{ans2030}}`.
25
+ - **Articles** : même inspecteur de blocs, planification, révisions.
26
+ - **SEO (type Yoast/Rank Math)** : analyse en direct (score SEO + lisibilité), aperçu Google desktop/mobile au pixel, Open Graph/Twitter, robots/canonical ; réglages globaux, redirections 301/302, sitemap & robots.txt ; Google Search Console (connexion, propriété, requêtes, pages).
27
+ - **Menus** : principal, mobile, pied de page — glisser-déposer, sous-menus, bouton mis en avant, aperçu desktop/mobile ; le site public lit ces menus.
28
+ - **Formulaires** : boîte de réception (lu/non lu, archive, CSV, réponse e-mail) + constructeur de champs visuel.
29
+ - **Boutons flottants** : barre mobile (par défaut « Appeler » / « Parler de votre projet »).
30
+ - **Apparence** : thèmes installés et marketplace de thèmes (import `.snaptheme`, aperçu avant activation), personnalisation des options du thème actif avec aperçu en direct, identité visuelle. La landing d’origine est le thème **SidiBou** — voir [MODULES.md](MODULES.md#10-thèmes).
31
+ - **Modules** : marketplace (catalogue local ou distant, import `.snapmod`), modules installés avec réglages générés, licence et contrôle d’intégrité. WhatsApp et Chat IA (modèle, température, quotas, prompt système, usage du jour) sont livrés comme modules — voir [MODULES.md](MODULES.md).
32
+ - **Newsletter** : abonnés, double opt-in, export CSV.
33
+ - **Identité visuelle** : logos (en-tête, pied de page), favicon, 8 couleurs du thème, polices — avec aperçu réel du site (choix de la page et de l’écran) avant enregistrement.
34
+ - **Infos générales, maintenance** (IP autorisées + lien de prévisualisation secret).
35
+
36
+ ## Paramètres avancés (`/administrator/settings`)
37
+
38
+ Réservés à la permission « Modifier les paramètres avancés ». Chaque onglet signale les modifications non enregistrées ; les valeurs hors bornes sont refusées avant l’envoi (et revérifiées côté serveur).
39
+
40
+ | Onglet | Réglages |
41
+ |--------|----------|
42
+ | Général | URL publique, statistiques et bandeau cookies, état des services connectés (SMTP, Google, Gemini, clé de chiffrement) |
43
+ | E-mails | Serveur SMTP (préréglages Gmail, Microsoft 365, OVH, Brevo, Mailgun, SendGrid, Amazon SES ; chiffrement, délai, certificat auto-signé), expéditeur et adresse de réponse, envoi de test, alertes de sécurité et de comptes, journal des e-mails envoyés |
44
+ | Sécurité | Politique de mot de passe (longueur, majuscule, chiffre, symbole, expiration), durée de session, « rester connecté », déconnexion après inactivité, verrouillage après échecs de connexion, double authentification (facultative / super administrateurs / tous), liste d’IP autorisées pour l’administration, HSTS |
45
+ | Limites | Requêtes par minute (site public, administration), quotas des formulaires, de la newsletter et du mot de passe oublié |
46
+ | Médias | Taille maximale, types autorisés (images, SVG, vidéos, PDF) |
47
+ | Données | Durées de conservation (statistiques, messages, journal d’activité, journal des e-mails), stockage de l’IP des expéditeurs, purge immédiate |
48
+ | Système | Version, environnement, base de données, volume de contenu, durée du cache public |
49
+
50
+ Le mot de passe SMTP et les secrets 2FA sont chiffrés en base avec `SNAPIFY_SECRET_KEY` (à défaut `ADMIN_JWT_SECRET`). Le SMTP configuré ici a priorité sur les variables `SMTP_*` du `.env`.
51
+
52
+ Garde-fous : impossible d’enregistrer une liste d’IP qui exclut votre propre adresse, ni d’imposer la 2FA à un groupe dont vous faites partie sans l’avoir activée vous-même. En cas de blocage par la liste d’IP, démarrer avec `SNAPIFY_ADMIN_IP_BYPASS=true`.
53
+
54
+ ## Utilisateurs, rôles et profil
55
+
56
+ **Utilisateurs** (`/administrator/users`)
57
+ - Invitation par e-mail (lien valable 7 jours, renvoyable) ou création avec mot de passe (générateur conforme à la politique, changement imposé à la première connexion). Sans SMTP, le lien est affiché pour être copié.
58
+ - Par compte : modifier nom, fonction, téléphone, e-mail et rôle ; lien de réinitialisation ; définir un mot de passe ; réinitialiser la 2FA ; fermer les sessions ; suspendre / réactiver ; supprimer (ou annuler l’invitation). Fiche détaillée avec sessions ouvertes et activité.
59
+ - Filtres par rôle et statut (dont « actifs sans 2FA »), recherche.
60
+
61
+ **Rôles** — rôles fournis : Super administrateur, Éditeur, Contributeur, Référenceur SEO, Lecteur. Le super administrateur peut créer, dupliquer, modifier, réinitialiser et supprimer des rôles (les comptes concernés sont réaffectés) ; 25 permissions réparties en 7 groupes, avec matrice récapitulative. Règles :
62
+ - on ne peut gérer ou attribuer qu’un rôle dont les permissions sont incluses dans les siennes ;
63
+ - le dernier super administrateur actif ne peut être ni rétrogradé, ni suspendu, ni supprimé ;
64
+ - sans droit de publication, une page ou un article déjà en ligne passe en lecture seule (le référencement reste modifiable avec le droit SEO).
65
+
66
+ **Journal d’activité** — toutes les actions sensibles (connexions, échecs, comptes, rôles, contenus, paramètres), filtres par catégorie, utilisateur et dates, export CSV.
67
+
68
+ **Mon profil** (`/administrator/profile`) — informations personnelles (le changement d’e-mail demande le mot de passe), mot de passe, double authentification TOTP avec codes de secours, sessions ouvertes (fermer une session ou toutes les autres), activité personnelle et liste de ses droits.
69
+
70
+ **Connexion** — mot de passe oublié, 2FA (application ou code de secours), verrouillage temporaire après trop d’échecs, écrans imposés (changement de mot de passe, activation de la 2FA) lorsque la politique l’exige.
71
+
72
+ ## Base de données (PostgreSQL)
73
+
74
+ - Conteneur dédié : `docker-compose.db.yml` (`npm run db:up`), volume persistant `snapify_pgdata`, accessible uniquement en local.
75
+ - ORM : Drizzle — schéma `server/db/schema.ts`, migrations SQL versionnées dans `drizzle/`, appliquées automatiquement au démarrage.
76
+ - Tables : `pages`, `posts`, `revisions` (50 max par contenu), `menus`, `redirects`, `forms`, `form_submissions`, `newsletter_subscribers`, `media`, `admin_users`, `analytics_events` (rétention 400 jours, purge quotidienne), `site_settings` (réglages par section), `modules` et `module_storage` (modules et thèmes installés — colonne `kind` — et leurs données).
77
+ - Statistiques calculées en SQL (agrégats indexés), sans chargement des événements en mémoire.
78
+ - Modifier le schéma : éditer `server/db/schema.ts` → `npm run db:generate` → redémarrer.
79
+ - Sauvegarde manuelle : `npm run db:backup` · Restauration : `npm run db:restore -- backups/db/<fichier>.dump`.
80
+ - Ne pas modifier les tables CMS directement en SQL pendant que le serveur tourne (le serveur garde l'état en cache) : passer par le backoffice, ou redémarrer après.
81
+ - L'ancien `data/cms/snapshot.json` a été importé puis renommé `snapshot.json.imported-*` (copie de sécurité aussi dans `backups/`).
82
+
83
+ ## Configuration production
84
+
85
+ ```env
86
+ DATABASE_URL=postgres://snapify:***@127.0.0.1:5433/snapify
87
+ SNAPIFY_DB_PASSWORD=
88
+
89
+ GEMINI_API_KEY=
90
+ ADMIN_JWT_SECRET=
91
+ ADMIN_PASSWORD=
92
+ SNAPIFY_SECRET_KEY= # chiffrement des secrets en base — ne plus changer une fois défini
93
+ SNAPIFY_ADMIN_URL=https://votre-domaine.fr/administrator # liens des e-mails d’invitation
94
+ SNAPIFY_ADMIN_IP_BYPASS=false
95
+
96
+ # Facultatif : les identifiants Google se saisissent aussi dans SEO › Google Search Console
97
+ GOOGLE_CLIENT_ID=
98
+ GOOGLE_CLIENT_SECRET=
99
+ GOOGLE_REDIRECT_URI=https://votre-domaine.fr/api/admin/google/callback # utilisé seulement avec les identifiants du .env
100
+
101
+ SMTP_HOST=
102
+ SMTP_PORT=587
103
+ SMTP_USER=
104
+ SMTP_PASS=
105
+ SMTP_FROM=contact@snapify.fr
106
+ ```
107
+
108
+ ## Connexion Google Search Console
109
+
110
+ Firebase n’est pas nécessaire : tout se fait dans Google Cloud Console (gratuit, environ 5 minutes). L’assistant **SEO › Google Search Console** guide pas à pas :
111
+
112
+ 1. Créer un projet Google Cloud.
113
+ 2. Activer l’API « Google Search Console API ».
114
+ 3. Configurer l’écran de consentement (type « Externe »), puis le **publier** : en mode « Test », Google expire la connexion au bout de 7 jours.
115
+ 4. Créer un client OAuth « Application Web » avec l’origine JavaScript et l’URI de redirection affichées par l’assistant (`https://votre-domaine.fr/api/admin/google/callback` ; en local `http://localhost:3010/api/admin/google/callback`).
116
+ 5. Coller l’ID client et le code secret (ou importer le fichier JSON téléchargé) : Snapify les vérifie auprès de Google et chiffre le secret en base.
117
+
118
+ Il reste ensuite à cliquer sur « Se connecter avec Google » avec un compte ayant accès à la propriété dans Search Console. Les erreurs de retour (`redirect_uri_mismatch`, accès refusé, API désactivée…) sont expliquées dans l’admin, avec une section « Problèmes fréquents ». Les identifiants saisis dans l’admin sont prioritaires sur ceux du `.env`.
119
+
120
+ ## Ajouter une réalisation
121
+
122
+ 1. **Pages** → nouvelle page `/realisations/<nom>/`
123
+ 2. Onglet **Page** → Modèle « Réalisation » → remplir la fiche (client, secteur, image, résultats)
124
+ 3. Composer les blocs, publier : elle apparaît automatiquement dans les blocs « Réalisations » (accueil, secteurs, liste).
125
+
126
+ ## Code
127
+
128
+ - Modèle des blocs : `server/cms/blocks.ts` · catalogue (libellés, valeurs par défaut) : `server/cms/blockCatalog.ts`
129
+ - Rendu public : `src/components/cms/` · formulaires de l’inspecteur : `src/admin/editor/blockSchemas.ts`
130
+ - Ajouter un type de bloc : type dans `blocks.ts` → entrée du catalogue → composant de rendu (`BlockRenderer.tsx`) → schéma de champs (`blockSchemas.ts`).
@@ -0,0 +1,66 @@
1
+ # CI / CD Snapify
2
+
3
+ ## Dépôt
4
+
5
+ - GitHub : https://github.com/hamdiayari-backup/snapify (privé)
6
+ - Branche de production : `main`
7
+
8
+ ## Versions (SemVer)
9
+
10
+ | Commande | Effet |
11
+ |----------|--------|
12
+ | `npm version patch` | 1.1.0 → 1.1.1 |
13
+ | `npm version minor` | 1.1.0 → 1.2.0 |
14
+ | `npm version major` | 1.1.0 → 2.0.0 |
15
+
16
+ Puis : `git push origin main --follow-tags`
17
+ Le workflow **Release** crée la release GitHub + archive `dist` sur chaque tag `v*.*.*`.
18
+
19
+ Depuis GitHub : Actions → **Release** → Run workflow → choisir patch / minor / major.
20
+
21
+ ## Workflows
22
+
23
+ Tous tournent sur le **runner self-hosted `hamdi`** (ce serveur).
24
+
25
+ | Fichier | Déclencheur | Rôle |
26
+ |---------|-------------|------|
27
+ | `ci.yml` | push / PR `main` | `tsc` + `vite build` |
28
+ | `deploy.yml` | push `main` ou manuel | `scripts/deploy.sh` en local |
29
+ | `release.yml` | tag `v*` ou manuel | GitHub Release + archive `dist` |
30
+
31
+ ## Serveur (alias SSH `hamdi`)
32
+
33
+ ```sshconfig
34
+ Host hamdi
35
+ HostName snapify.tn
36
+ User root
37
+ IdentityFile ~/.ssh/snapify_deploy
38
+ IdentitiesOnly yes
39
+ ```
40
+
41
+ Déploiement manuel :
42
+
43
+ ```bash
44
+ ssh hamdi 'bash /home/snapify/scripts/deploy.sh origin/main'
45
+ # ou sur le serveur :
46
+ bash /home/snapify/scripts/deploy.sh origin/main
47
+ ```
48
+
49
+ ## Runner GitHub Actions
50
+
51
+ - Service systemd : `actions.runner.hamdiayari-backup-snapify.hamdi`
52
+ - Labels : `self-hosted`, `hamdi`, `production`
53
+ - Auth SSH : mots de passe désactivés ; alias `hamdi` → `snapify.tn` (clé `~/.ssh/snapify_deploy`)
54
+
55
+ Si les workflows restent en **`startup_failure`** (compte GitHub free / Actions non facturés) :
56
+
57
+ 1. Vérifier sur GitHub → Settings → Actions → General → **Allow all actions**
58
+ 2. Ou compter sur le **timer systemd** local (secours) :
59
+
60
+ ```bash
61
+ systemctl status snapify-auto-deploy.timer
62
+ # toutes les 5 min : git fetch + deploy si origin/main a avancé
63
+ ```
64
+
65
+ Le fichier `.env` **reste uniquement sur le serveur** (jamais dans Git).
66
+
@@ -0,0 +1,346 @@
1
+ <!--
2
+ Snapify
3
+ © 2026 NOVALABS WEB DESIGN — Tunisie
4
+ Contact : contact@novalabs.tn · +216 24 734 647
5
+ Tous droits réservés. Toute reproduction, modification ou diffusion sans autorisation écrite est interdite.
6
+ -->
7
+
8
+ # Modules et thèmes Snapify — guide développeur
9
+
10
+ > Version publique et à jour de ce guide : https://developers.snapify.tn
11
+
12
+ > Les thèmes (`.snaptheme`) reposent sur le même système de paquets, de signature et de licence : voir la [section 10](#10-thèmes).
13
+
14
+ Un module ajoute une fonctionnalité au CMS sans toucher au cœur : un composant affiché sur le site, éventuellement une API côté serveur, et des réglages que l'administration génère automatiquement à partir du manifeste.
15
+
16
+ Les modules sont distribués sous forme de paquets **`.snapmod` signés par NOVALABS**. Un site Snapify n'installe que des paquets dont la signature est valide (sauf en mode développeur), revérifie l'intégrité de chaque fichier à chaque démarrage et contrôle la licence du module.
17
+
18
+ Modules de référence : [`modules/whatsapp`](../modules/whatsapp) (public uniquement) et [`modules/ai-chat`](../modules/ai-chat) (public + serveur).
19
+
20
+ ---
21
+
22
+ ## 1. Structure d'un module
23
+
24
+ ```
25
+ modules/mon-module/
26
+ ├── snapify.module.json # manifeste (obligatoire)
27
+ ├── README.md # optionnel, inclus dans le paquet
28
+ └── src/
29
+ ├── public.tsx # composant(s) affiché(s) sur le site
30
+ └── server.ts # code serveur (optionnel)
31
+ ```
32
+
33
+ Les sources importent uniquement `react`, `@snapify/sdk` et des dépendances qui seront intégrées au bundle (ex. `lucide-react`). React est partagé avec le site : il n'est jamais embarqué dans le module.
34
+
35
+ ## 2. Manifeste `snapify.module.json`
36
+
37
+ ```json
38
+ {
39
+ "id": "editeur.mon-module",
40
+ "name": "Mon module",
41
+ "version": "1.0.0",
42
+ "description": "Ce que fait le module, en une ou deux phrases.",
43
+ "author": { "name": "Éditeur", "email": "contact@editeur.tn", "url": "https://editeur.tn" },
44
+ "pricing": "free",
45
+ "category": "Contact",
46
+ "icon": "sparkles",
47
+ "engines": { "snapify": "^1.0.0" },
48
+ "permissions": ["http:routes"],
49
+ "slots": ["floating"],
50
+ "entries": { "public": "src/public.tsx", "server": "src/server.ts" },
51
+ "settings": [
52
+ { "key": "title", "type": "text", "group": "Apparence", "label": "Titre", "default": "Bonjour", "public": true, "maxLength": 60 }
53
+ ]
54
+ }
55
+ ```
56
+
57
+ | Champ | Règle |
58
+ | --- | --- |
59
+ | `id` | `editeur.nom`, minuscules, chiffres et tirets (`^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$`). Ne change jamais. |
60
+ | `version` | SemVer `x.y.z`. Une version supérieure est proposée comme mise à jour. |
61
+ | `pricing` | `free` ou `paid`. Un module payant exige une licence pour s'activer. |
62
+ | `icon` | `bot`, `calendar`, `chart-bar`, `database`, `globe`, `mail`, `message-circle`, `messages-square`, `phone`, `search`, `shopping-cart`, `sparkles` (sinon icône générique). |
63
+ | `engines.snapify` | Version d'API requise : `*`, `1.0.0`, `>=1.0.0` ou `^1.0.0`. L'API actuelle est `1.3.0`. |
64
+ | `slots` | Emplacements où le module s'affiche. Disponible : `floating` (éléments fixés à l'écran). |
65
+ | `entries` | `public` et/ou `server`, chemins relatifs vers les sources. |
66
+
67
+ ### Réglages
68
+
69
+ Chaque entrée de `settings` devient un champ dans l'administration (page du module). Les valeurs sont validées côté serveur avant d'être enregistrées.
70
+
71
+ | `type` | Valeur | Options utiles |
72
+ | --- | --- | --- |
73
+ | `boolean` | `true` / `false` | |
74
+ | `text`, `phone` | chaîne | `maxLength`, `placeholder` |
75
+ | `textarea` | chaîne | `rows`, `maxLength`, `monospace` |
76
+ | `number` | nombre | `min`, `max`, `step`, `slider` |
77
+ | `select` | une des `options[].value` | `options` |
78
+ | `paths` | liste d'adresses (`/contact/`, `/blog/*`) | vide = toutes les pages |
79
+
80
+ Options communes : `key`, `label`, `help`, `group` (titre de la section), `default`, `required`.
81
+
82
+ **`public: true`** expose la valeur au navigateur. Tout ce qui n'est pas marqué `public` (prompt système, quotas, choix du modèle…) reste exclusivement côté serveur.
83
+
84
+ ## 3. Partie publique
85
+
86
+ ```tsx
87
+ import { definePublicModule, matchesPaths, type PublicModuleProps } from '@snapify/sdk';
88
+
89
+ interface Settings { title: string; showOnPages: string[] }
90
+
91
+ function Widget({ settings, site, path, isPreview, navigate, api }: PublicModuleProps<Settings>) {
92
+ if (!matchesPaths(settings.showOnPages, path)) return null;
93
+ return (
94
+ <button className="fixed bottom-5 right-5 rounded-full bg-px-primary px-4 py-2 text-white" onClick={() => navigate('/contact/')}>
95
+ {settings.title} — {site.name}
96
+ </button>
97
+ );
98
+ }
99
+
100
+ export default definePublicModule<Settings>({ slots: { floating: Widget } });
101
+ ```
102
+
103
+ Props reçues :
104
+
105
+ - `settings` : réglages publics ;
106
+ - `site` : nom, téléphone, e-mail, adresse du site ;
107
+ - `path` : page affichée ; `isPreview` : `true` dans l'aperçu de l'éditeur ;
108
+ - `navigate(path)` : navigation interne sans rechargement ;
109
+ - `api.get(route)` / `api.post(route, body)` : appels vers la partie serveur du module (`/api/modules/<id>/<route>`).
110
+
111
+ **Styles.** Tailwind est compilé avec le module ; seules les classes réellement utilisées sont incluses. Les couleurs du site sont disponibles via `px-*` (`bg-px-primary`, `text-px-navy`…), ce qui garde le module aligné sur l'identité visuelle choisie dans l'administration. À la compilation, la feuille de style est limitée au conteneur du module (`[data-snapify-scope="<id>"]`) : elle ne peut pas modifier l'apparence du thème ni des autres modules. Une erreur dans un module est isolée : elle n'affecte ni le site ni les autres modules.
112
+
113
+ ## 4. Partie serveur
114
+
115
+ ```ts
116
+ import { defineServerModule, type ServerContext } from '@snapify/sdk';
117
+
118
+ interface Settings { greeting: string }
119
+
120
+ export default defineServerModule<Settings>({
121
+ activate(ctx: ServerContext<Settings>) {
122
+ ctx.http.post('/hello', async (req) => {
123
+ const name = typeof req.body?.name === 'string' ? req.body.name.slice(0, 50) : '';
124
+ if (!name) throw ctx.error(400, 'Nom manquant');
125
+ const count = ((await ctx.storage.get<number>('count')) ?? 0) + 1;
126
+ await ctx.storage.set('count', count);
127
+ return { message: `${ctx.settings().greeting} ${name}`, count };
128
+ });
129
+
130
+ ctx.admin.status(async () => ({
131
+ stats: [{ label: 'Appels', value: (await ctx.storage.get<number>('count')) ?? 0 }],
132
+ }));
133
+ },
134
+ });
135
+ ```
136
+
137
+ Chaque capacité du contexte est liée à une permission déclarée dans le manifeste ; sans elle, l'appel échoue.
138
+
139
+ | API | Permission | Rôle |
140
+ | --- | --- | --- |
141
+ | `ctx.http.get/post(route, handler)` | `http:routes` | Routes publiques sous `/api/modules/<id>/…` (120 requêtes/min/IP, 60 s max). |
142
+ | `ctx.env(NOM)` | `env:NOM` | Lire une variable d'environnement précise (clé d'API…). |
143
+ | `ctx.fetch(url, init)` | `net:hôte` ou `net:outbound` | HTTPS vers un hôte déclaré, ou HTTP(S) public anti-SSRF (`net:outbound`, redirections limitées). |
144
+ | `ctx.ftp.list` / `ctx.ftp.readText` | `net:ftp` | Lecture FTP/FTPS contrôlée (exports SEO, `.htaccess`…) — pas de socket brut dans le module. |
145
+ | `ctx.site()` | `site:read` | Informations publiques du site (nom, coordonnées, couleurs, URL). |
146
+ | `ctx.storage.get/set/delete` | `storage` | Données propres au module, en base (supprimées à la désinstallation). |
147
+ | `ctx.settings()`, `ctx.log`, `ctx.error()`, `ctx.admin.status()` | — | Toujours disponibles. |
148
+
149
+ `ctx.error(status, message)` renvoie une erreur propre au visiteur ; toute autre exception renvoie une erreur 500 générique et est journalisée côté serveur. `ctx.admin.status()` alimente les statistiques et alertes affichées en haut de la page du module dans l'administration.
150
+
151
+ ## 5. Construire, signer, publier
152
+
153
+ Commandes (depuis la racine du projet) :
154
+
155
+ ```bash
156
+ # Construire et signer un paquet (sortie : marketplace/packages/<id>-<version>.snapmod)
157
+ SNAPIFY_SIGNING_KEY=~/.snapify/keys/novalabs-2026.pem npm run module -- build modules/mon-module
158
+
159
+ # Paquet non signé, pour tester en mode développeur
160
+ npm run module -- build modules/mon-module --unsigned
161
+
162
+ # Vérifier un paquet (signature, empreintes, manifeste)
163
+ npm run module -- verify marketplace/packages/editeur.mon-module-1.0.0.snapmod
164
+
165
+ # Régénérer le catalogue local marketplace/catalog.json
166
+ npm run module -- catalog
167
+
168
+ # Émettre une licence (module payant ou licence nominative)
169
+ SNAPIFY_SIGNING_KEY=… npm run module -- license --module editeur.mon-module \
170
+ --licensee "Client SARL" --domains client.tn,*.client.tn --plan standard --expires 2027-12-31
171
+
172
+ # Créer une nouvelle paire de clés (une seule fois, à conserver hors du dépôt)
173
+ npm run module -- keygen --out ~/.snapify/keys --kid novalabs-2027
174
+ ```
175
+
176
+ La clé publique affichée par `keygen` doit être ajoutée à `TRUSTED_KEYS` dans `server/modules/trust.ts` ; c'est ce qui permet de faire tourner les clés sans invalider les paquets existants. **La clé privée ne doit jamais être versionnée ni copiée sur un serveur de production.**
177
+
178
+ Pour un module gratuit signé, `build` intègre automatiquement une licence gratuite valable sur tous les domaines.
179
+
180
+ ### Développeurs tiers
181
+
182
+ Les développeurs externes n'ont pas accès à ce dépôt : ils utilisent le kit public publié sur npm (documentation :
183
+ https://developers.snapify.tn/docs/kit-developpeur).
184
+
185
+ 1. `npm create snapify@latest` crée le projet ; `npm run build` produit un paquet non signé et rejoue l'analyse marketplace.
186
+ 2. Ils testent sur un site en mode développeur (`SNAPIFY_MODULES_DEV_MODE=true`), s'ils en ont un.
187
+ 3. Ils envoient le paquet depuis leur espace vendeur de la marketplace ; NOVALABS le relit, le teste, puis le signe à l'approbation.
188
+
189
+ ### Kit développeur public (npm)
190
+
191
+ Sources : `sdk-kit/` (outil `snapify`, modèles, README, licence, journal des versions) et `sdk-kit/create-snapify/`.
192
+ Paquets npm : `snapify-sdk` (SDK + outil, importé par les projets sous l'alias `@snapify/sdk`) et `create-snapify`
193
+ (`npm create snapify`), publiés par le compte npm de NOVALABS. Le nom `snapify` n'est pas disponible sur npm.
194
+
195
+ ```bash
196
+ # 1. Augmenter "version" dans sdk-kit/package.template.json et compléter sdk-kit/CHANGELOG.md
197
+ # 2. Construire : releases/sdk/ (téléchargements du portail, sommes SHA-256, index.json) et releases/npm/
198
+ npm run sdk:pack
199
+ # 3. Contrôler sans publier
200
+ npm run sdk:publish -- --dry-run
201
+ # 4. Publier snapify-sdk puis create-snapify (double authentification du compte npm requise)
202
+ npm run sdk:publish -- --otp 123456
203
+ # ou, avec une clé de sécurité / Windows Hello : approbation dans le navigateur
204
+ npx -y npm@11 publish releases/npm/snapify-sdk-<version>.tgz --access public --auth-type=web
205
+ npx -y npm@11 publish releases/npm/create-snapify-<version>.tgz --access public --auth-type=web
206
+ ```
207
+
208
+ Une version publiée sur npm ne peut plus être modifiée : toute correction passe par une nouvelle version. `sdk:pack` refuse
209
+ d'écraser une version existante (`--force` réservé aux essais locaux, jamais après publication). Le script de publication vérifie
210
+ que l'archive npm est identique au téléchargement de developers.snapify.tn.
211
+
212
+ ## 6. Format du paquet `.snapmod`
213
+
214
+ JSON compressé en gzip :
215
+
216
+ ```json
217
+ {
218
+ "format": "snapmod/1",
219
+ "manifest": { "…manifeste…": "", "entries": { "public": "public.js", "server": "server.mjs" }, "styles": "public.css",
220
+ "files": { "public.js": { "sha256": "…", "size": 1234 } }, "builtAt": "…" },
221
+ "files": { "public.js": "<base64>", "public.css": "<base64>", "server.mjs": "<base64>" },
222
+ "signature": { "alg": "ed25519", "kid": "novalabs-2026", "value": "<base64>" },
223
+ "license": "SNAPIFY-LIC-…"
224
+ }
225
+ ```
226
+
227
+ - La signature Ed25519 porte sur le JSON canonique (clés triées) du manifeste, qui contient l'empreinte SHA-256 et la taille de chaque fichier : modifier un seul octet invalide le paquet.
228
+ - Fichiers autorisés : `public.js`, `public.css`, `server.mjs`, `README.md`. Taille maximale : 20 Mo compressé, 40 Mo décompressé.
229
+ - Licence : `SNAPIFY-LIC-` + base64url de `{ payload: { v, licenseId, moduleId, licensee, plan, domains, issuedAt, expiresAt }, signature }`. Elle est vérifiée hors ligne : signature, module, date d'expiration, et domaine de l'URL publique du site (Paramètres). `*` couvre tous les domaines, `*.exemple.fr` les sous-domaines ; `localhost` est toujours accepté.
230
+
231
+ ## 7. Catalogue distant
232
+
233
+ Par défaut, la marketplace lit `marketplace/catalog.json`. Pour un catalogue central, définissez `MARKETPLACE_URL` (HTTPS obligatoire) vers un fichier au même format :
234
+
235
+ ```json
236
+ {
237
+ "format": "snapify-catalog/1",
238
+ "modules": [
239
+ { "id": "…", "name": "…", "version": "…", "…": "champs du manifeste",
240
+ "package": "packages/editeur.mon-module-1.0.0.snapmod", "sha256": "…", "size": 15739, "signed": true }
241
+ ]
242
+ }
243
+ ```
244
+
245
+ `package` est résolu relativement à l'URL du catalogue. Le paquet téléchargé doit correspondre à `sha256`, puis passe par les mêmes vérifications qu'un import manuel. En cas d'indisponibilité, le catalogue local est affiché.
246
+
247
+ ## 8. Modèle de sécurité
248
+
249
+ | Contrôle | Moment |
250
+ | --- | --- |
251
+ | Signature NOVALABS du manifeste et empreintes des fichiers | Import, téléchargement, chaque démarrage, chaque activation |
252
+ | Compatibilité de l'API (`engines.snapify`) | Installation et démarrage |
253
+ | Licence (signature, module, domaine, expiration) | Installation, saisie de clé, démarrage, toutes les 10 minutes |
254
+ | Permissions du contexte serveur | À chaque appel |
255
+ | Réglages validés selon leur schéma ; seuls les réglages `public` atteignent le navigateur | Enregistrement et diffusion |
256
+ | Fichiers publics servis depuis la copie vérifiée en mémoire ; `server.mjs` jamais exposé | Chaque requête |
257
+
258
+ Un module dont un contrôle échoue est **bloqué** (non chargé sur le site, routes désactivées) et signalé dans l'administration avec la raison. Une réinstallation depuis la marketplace répare un module altéré en conservant ses réglages.
259
+
260
+ **Limite à connaître :** le code serveur d'un module s'exécute dans le processus Node du site. Les permissions encadrent l'API fournie, mais ne constituent pas un bac à sable : un code malveillant pourrait importer directement des modules Node. C'est pourquoi la confiance repose sur la **revue et la signature par NOVALABS** ; le mode développeur, qui accepte les paquets non signés, ne doit jamais être activé en production.
261
+
262
+ ## 9. Administration
263
+
264
+ - **Marketplace** (super administrateur) : catalogue, installation et mise à jour, import manuel d'un `.snapmod`. Chaque installation passe par un écran de confirmation qui montre la provenance, la signature, la licence et les permissions demandées.
265
+ - **Modules installés** (super administrateur et éditeur) : état, activation, accès aux réglages. Chaque module configurable a aussi son entrée dans le menu.
266
+ - **Page du module** : statistiques fournies par le module, réglages générés, licence (saisie ou remplacement de clé), sécurité et permissions, désinstallation.
267
+
268
+ Les fichiers installés se trouvent dans `data/modules/<id>/<version>/`, l'état et les réglages dans les tables `modules` et `module_storage`.
269
+
270
+ ## 10. Thèmes
271
+
272
+ Un thème fournit toute la présentation du site : en-tête, pied de page, rendu des 25 types de blocs, mise en page des pages et des articles, page 404. Le contenu (pages, menus, articles, identité visuelle) ne dépend pas du thème : changer de thème ne modifie aucune donnée. Le site hôte garde la navigation, le chargement des données, l'aperçu de l'éditeur, la bannière cookies, le mode maintenance, les statistiques et les modules.
273
+
274
+ Le thème livré par défaut, **SidiBou** (`novalabs.sidibou`), est la landing d'origine. Ses sources sont dans `themes/sidibou/` et servent d'exemple complet.
275
+
276
+ ### Structure
277
+
278
+ ```
279
+ themes/mon-theme/
280
+ snapify.theme.json manifeste (mêmes champs qu'un module, sans permissions ni slots)
281
+ screenshot.jpg capture 4:3 (JPEG, PNG ou WebP, 2 Mo max), affichée dans l'administration
282
+ src/index.tsx point d'entrée : export default defineTheme({...})
283
+ src/styles.css importé depuis l'entrée ; Tailwind est disponible
284
+ ```
285
+
286
+ Différences avec un module : `kind` vaut `theme` (déduit du nom du manifeste), `entries.public` est obligatoire, `entries.server`, `permissions` et `slots` sont interdits. Les réglages (`settings`) deviennent les **options du thème**, toutes transmises au navigateur et modifiables dans *Apparence > Personnaliser*.
287
+
288
+ ### Contrat
289
+
290
+ ```tsx
291
+ import { defineTheme, useSnapify } from '@snapify/sdk/theme';
292
+ import type { BlockProps } from '@snapify/sdk/theme';
293
+
294
+ function Header({ path, navigate }) {
295
+ const { site, info, settings } = useSnapify<{ sticky: boolean }>();
296
+ // site : configuration publique (menus, identité visuelle…), info : coordonnées
297
+ return <header>…</header>;
298
+ }
299
+
300
+ export default defineTheme({
301
+ Header,
302
+ Footer: ({ navigate, openCookies }) => <footer>…</footer>,
303
+ Layout: ({ children }) => <>{children}</>, // facultatif : applique les options
304
+ Page: ({ page, children }) => <main>{children}</main>, // facultatif
305
+ Post: ({ post, children }) => <article>{children}</article>, // facultatif
306
+ NotFound: ({ navigate }) => <p>Page introuvable</p>, // facultatif
307
+ blocks: {
308
+ hero: ({ d, style }: BlockProps<'hero'>) => <section>{d.title}</section>,
309
+ // un bloc sans rendu n'est pas affiché (l'aperçu de l'éditeur le signale)
310
+ },
311
+ });
312
+ ```
313
+
314
+ - `@snapify/sdk/theme` : `defineTheme`, `useSnapify()` (site, coordonnées, variables `{{…}}`, options, adresse, navigation, `isPreview`), `isPreviewMode()`.
315
+ - `@snapify/sdk/content` : types des blocs, pages, articles et de la configuration, `applyTokens()`.
316
+ - `@snapify/sdk/icons` : icônes disponibles dans l'éditeur de blocs.
317
+
318
+ React est fourni par le site (non inclus dans le bundle). Chaque partie du thème est isolée : une erreur dans un bloc, l'en-tête ou le pied de page n'affecte pas le reste de la page.
319
+
320
+ ### Construire et publier
321
+
322
+ Mêmes commandes que pour un module ; le paquet produit est un `.snaptheme` :
323
+
324
+ ```bash
325
+ SNAPIFY_SIGNING_KEY=~/.snapify/keys/novalabs-2026.pem npm run module -- build themes/mon-theme
326
+ npm run module -- catalog # ajoute le thème et sa capture (marketplace/screenshots/)
327
+ ```
328
+
329
+ Dans un catalogue distant, une entrée de thème porte `"kind": "theme"` et `"screenshot"` (chemin relatif au catalogue, servi en HTTPS).
330
+
331
+ ### Fonctionnement
332
+
333
+ - Un seul thème est actif à la fois. Un thème installé n'est pas activé automatiquement s'il en existe déjà un actif.
334
+ - Au premier démarrage, SidiBou est installé depuis le catalogue local et activé.
335
+ - La feuille de style, le script et la description du thème actif sont inclus dans le HTML : pas de flash sans style, et un changement de thème est visible immédiatement.
336
+ - **Aperçu** : un thème installé mais inactif peut être prévisualisé (et ses options réglées) dans *Personnaliser* avant activation. Ses fichiers sont servis à cette fin dès lors que ses vérifications sont satisfaites.
337
+ - Signature, empreintes, licence et compatibilité sont contrôlées comme pour les modules. Si le thème actif est bloqué, le site s'affiche avec un rendu minimal (menu, titres, textes) en attendant une réparation ou l'activation d'un autre thème.
338
+ - Le thème actif ne peut pas être supprimé.
339
+
340
+ ### Administration
341
+
342
+ Menu **Apparence** :
343
+
344
+ - **Thèmes** : thèmes installés (capture, activation, aperçu, suppression), onglet *Ajouter un thème* alimenté par la marketplace, import manuel d'un `.snaptheme`.
345
+ - **Personnaliser** : options du thème avec aperçu en direct (ordinateur, tablette, mobile, choix de la page) ; pour un thème inactif, *Enregistrer et activer*.
346
+ - **Identité visuelle** : logo, couleurs et polices, communs à tous les thèmes (variables CSS `--px-*`).
@@ -0,0 +1,54 @@
1
+ # Community + Marketplace — déploiement
2
+
3
+ ## DNS
4
+
5
+ | Host | Cible |
6
+ |------|--------|
7
+ | `community.snapify.tn` | même serveur que `snapify.tn` |
8
+ | `marketplace.snapify.tn` | même serveur que `snapify.tn` |
9
+
10
+ ## Nginx (extrait)
11
+
12
+ ```nginx
13
+ server {
14
+ server_name community.snapify.tn marketplace.snapify.tn snapify.tn;
15
+ location / {
16
+ proxy_pass http://127.0.0.1:3020;
17
+ proxy_set_header Host $host;
18
+ proxy_set_header X-Forwarded-Host $host;
19
+ proxy_set_header X-Forwarded-Proto $scheme;
20
+ proxy_set_header X-Real-IP $remote_addr;
21
+ }
22
+ }
23
+ ```
24
+
25
+ ## Variables d’environnement
26
+
27
+ Voir `.env.example` : `COMMUNITY_HOST`, `MARKETPLACE_HOST`, `MARKETPLACE_PUBLIC_URL`,
28
+ `PLATFORM_COOKIE_DOMAIN=.snapify.tn`, clés Flouci, `FLOUCI_MOCK=false` en production.
29
+
30
+ Pour que le CMS Snapify installe depuis la marketplace en ligne :
31
+
32
+ ```env
33
+ MARKETPLACE_URL=https://marketplace.snapify.tn/api/marketplace/catalog.json
34
+ ```
35
+
36
+ ## Comptes seed
37
+
38
+ | Rôle | E-mail | Mot de passe (dev) |
39
+ |------|--------|--------------------|
40
+ | Admin plateforme | `PLATFORM_ADMIN_EMAIL` (défaut `admin@snapify.tn`) | `PLATFORM_ADMIN_PASSWORD` |
41
+ | Développeur démo | `dev@snapify.tn` | `Developer1` |
42
+
43
+ ## Dev local
44
+
45
+ Ajoutez dans `/etc/hosts` :
46
+
47
+ ```
48
+ 127.0.0.1 community.localhost marketplace.localhost
49
+ ```
50
+
51
+ Puis ouvrez `http://community.localhost:PORT` et `http://marketplace.localhost:PORT`.
52
+ Fallback : `http://localhost:PORT/?app=community` ou `?app=marketplace`.
53
+
54
+ Avec `FLOUCI_MOCK=true`, les paiements (achat + inscription 100 DT) sont confirmés immédiatement.