Arquitectura¶
Estructura del repositori¶
.
├── Codigo.gs # Nucli: CRUD reserves, auth, cache, doGet(), email
├── AdminFunctions.gs # Funcions admin: CRUD recursos/tramos/usuaris, estadístiques
├── ReservasRecurrentes.gs # Reserves recurrents (backend conservat, UI desactivada)
├── Incidencias.gs # Incidències: creació, actualització, resolució
├── Setup.gs # Wizard d'instal·lació: crea l'esquema de Sheets + dades mostra
├── index.html # UI principal (usuari)
├── admin-panel.html # Dashboard admin (pestanyes amb Tailwind)
├── scripts.html # JS del frontend d'usuari (~4000 línies)
├── admin-scripts.html # JS del frontend admin (~7100 línies, fitxer més gran)
├── styles.html # Tailwind CSS + estils personalitzats
├── i18n-core.html # Motor i18n: window.t(), applyI18n()
├── i18n-es.html # Diccionari castellà (~710 línies, ~400+ claus)
├── i18n-ca.html # Diccionari català (estructura idèntica a i18n-es.html)
├── Sidebar.html # Sidebar GAS per al wizard d'instal·lació
├── ActivacionSistema.html # Pàgina d'activació
├── registro.html # Formulari de sol·licitud d'accés
├── appsscript.json # Manifest GAS (runtime, timezone, webapp access)
└── docs/ # Documentació
Els fitxers
.js(AdminFunctions.js, Codigo.js...) són còpies antigues generades automàticament. No s'han de cometre — estan al.gitignore.
Punt d'entrada web: doGet()¶
Codigo.gs:681 — serveix la webapp. Injecta variables al template HTML:
template.userEmail // email de l'usuari autenticat
template.userName // nom de l'usuari
template.userRoleForJs // 'admin' | 'gestor' | 'usuari'
template.appLang // 'ca' | 'es' (de Config sheet)
El rol s'injecta com: window.USER_ROLE = '<?= userRoleForJs ?>' (amb cometes literals, no JSON.stringify — el sandbox GAS no ho suporta).
Sistema de rols¶
Tres rols mutualament exclusius, resolts a checkUserAuthorization() (Codigo.gs:273):
| Rol | Condició |
|---|---|
admin |
columna Admin=TRUE al full Usuarios |
gestor |
columna Gestor=TRUE i Admin≠TRUE |
usuari |
la resta d'usuaris registrats i actius |
La clau gestor_pestanyes a Config (default: reservas,estadistiques) determina quines pestanyes del panel admin veu el Gestor.
Flux de dades¶
Navegador
│
├─ doGet() ──────────────────────────────── Codigo.gs
│ └─ HtmlService.createTemplateFromFile()
│ └─ include('scripts'), include('i18n-es'), ...
│
├─ google.script.run.getStaticData() ────── Codigo.gs (CacheService)
│ └─ { recursos, tramos, cursos, usuaris }
│
├─ google.script.run.crearNuevaReserva() ── Codigo.gs
│ └─ validacions → escriptura a Sheets → email confirmació
│
└─ google.script.run.getAdminData() ─────── AdminFunctions.gs
└─ { reservas, recursos, usuaris, config, ... }