sum-cli 3.0.0__py3-none-any.whl

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 (72) hide show
  1. sum/__init__.py +1 -0
  2. sum/boilerplate/.env.example +124 -0
  3. sum/boilerplate/.gitea/workflows/ci.yml +33 -0
  4. sum/boilerplate/.gitea/workflows/deploy-production.yml +98 -0
  5. sum/boilerplate/.gitea/workflows/deploy-staging.yml +113 -0
  6. sum/boilerplate/.github/workflows/ci.yml +36 -0
  7. sum/boilerplate/.github/workflows/deploy-production.yml +102 -0
  8. sum/boilerplate/.github/workflows/deploy-staging.yml +115 -0
  9. sum/boilerplate/.gitignore +45 -0
  10. sum/boilerplate/README.md +259 -0
  11. sum/boilerplate/manage.py +34 -0
  12. sum/boilerplate/project_name/__init__.py +5 -0
  13. sum/boilerplate/project_name/home/__init__.py +5 -0
  14. sum/boilerplate/project_name/home/apps.py +20 -0
  15. sum/boilerplate/project_name/home/management/__init__.py +0 -0
  16. sum/boilerplate/project_name/home/management/commands/__init__.py +0 -0
  17. sum/boilerplate/project_name/home/management/commands/populate_demo_content.py +644 -0
  18. sum/boilerplate/project_name/home/management/commands/seed.py +129 -0
  19. sum/boilerplate/project_name/home/management/commands/seed_showroom.py +1661 -0
  20. sum/boilerplate/project_name/home/migrations/__init__.py +3 -0
  21. sum/boilerplate/project_name/home/models.py +13 -0
  22. sum/boilerplate/project_name/settings/__init__.py +5 -0
  23. sum/boilerplate/project_name/settings/base.py +348 -0
  24. sum/boilerplate/project_name/settings/local.py +78 -0
  25. sum/boilerplate/project_name/settings/production.py +106 -0
  26. sum/boilerplate/project_name/urls.py +33 -0
  27. sum/boilerplate/project_name/wsgi.py +16 -0
  28. sum/boilerplate/pytest.ini +5 -0
  29. sum/boilerplate/requirements.txt +25 -0
  30. sum/boilerplate/static/client/.gitkeep +3 -0
  31. sum/boilerplate/templates/overrides/.gitkeep +3 -0
  32. sum/boilerplate/tests/__init__.py +3 -0
  33. sum/boilerplate/tests/test_health.py +51 -0
  34. sum/cli.py +42 -0
  35. sum/commands/__init__.py +10 -0
  36. sum/commands/backup.py +308 -0
  37. sum/commands/check.py +128 -0
  38. sum/commands/init.py +265 -0
  39. sum/commands/promote.py +758 -0
  40. sum/commands/run.py +96 -0
  41. sum/commands/themes.py +56 -0
  42. sum/commands/update.py +301 -0
  43. sum/config.py +61 -0
  44. sum/docs/USER_GUIDE.md +663 -0
  45. sum/exceptions.py +45 -0
  46. sum/setup/__init__.py +17 -0
  47. sum/setup/auth.py +184 -0
  48. sum/setup/database.py +58 -0
  49. sum/setup/deps.py +73 -0
  50. sum/setup/git_ops.py +463 -0
  51. sum/setup/infrastructure.py +576 -0
  52. sum/setup/orchestrator.py +354 -0
  53. sum/setup/remote_themes.py +371 -0
  54. sum/setup/scaffold.py +500 -0
  55. sum/setup/seed.py +110 -0
  56. sum/setup/site_orchestrator.py +441 -0
  57. sum/setup/venv.py +89 -0
  58. sum/system_config.py +330 -0
  59. sum/themes_registry.py +180 -0
  60. sum/utils/__init__.py +25 -0
  61. sum/utils/django.py +97 -0
  62. sum/utils/environment.py +76 -0
  63. sum/utils/output.py +78 -0
  64. sum/utils/project.py +110 -0
  65. sum/utils/prompts.py +36 -0
  66. sum/utils/validation.py +313 -0
  67. sum_cli-3.0.0.dist-info/METADATA +127 -0
  68. sum_cli-3.0.0.dist-info/RECORD +72 -0
  69. sum_cli-3.0.0.dist-info/WHEEL +5 -0
  70. sum_cli-3.0.0.dist-info/entry_points.txt +2 -0
  71. sum_cli-3.0.0.dist-info/licenses/LICENSE +29 -0
  72. sum_cli-3.0.0.dist-info/top_level.txt +1 -0
sum/docs/USER_GUIDE.md ADDED
@@ -0,0 +1,663 @@
1
+ # SUM CLI User Guide (v3)
2
+
3
+ This guide covers the SUM Platform CLI tool v3, which provides commands for deploying and managing production SUM client sites.
4
+
5
+ ## Overview
6
+
7
+ The SUM CLI v3 (`sum-platform`) is the single control plane for the SUM site lifecycle:
8
+
9
+ - **`sum-platform init`** - Create new production sites at `/srv/sum/<name>/`
10
+ - **`sum-platform update`** - Update deployed sites (pull, migrate, restart)
11
+ - **`sum-platform backup`** - Backup database and media
12
+ - **`sum-platform promote`** - Deploy staging sites to production servers
13
+ - **`sum-platform check`** - Validate project setup
14
+ - **`sum-platform themes`** - List available themes
15
+ - **`sum-platform run`** - Start development server
16
+
17
+ ## Installation
18
+
19
+ ### Install from PyPI
20
+
21
+ ```bash
22
+ pip install sum-cli
23
+ sum-platform --version
24
+ ```
25
+
26
+ ### With Gitea Support
27
+
28
+ ```bash
29
+ pip install sum-cli[gitea]
30
+ ```
31
+
32
+ ### Monorepo Development Mode
33
+
34
+ From the repository root:
35
+
36
+ ```bash
37
+ source .venv/bin/activate
38
+ pip install -e ./cli
39
+ sum-platform --version
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Commands
45
+
46
+ ### `sum-platform init` - Create a New Site
47
+
48
+ Create a new production-ready site with full infrastructure provisioning.
49
+
50
+ **Requires sudo.** The init command provisions PostgreSQL databases, installs systemd services, and configures Caddy reverse proxy.
51
+
52
+ #### Basic Usage
53
+
54
+ ```bash
55
+ sudo sum-platform init <site-name> [options]
56
+ ```
57
+
58
+ #### What Init Does
59
+
60
+ 1. Validates prerequisites (sudo, postgres, git, systemctl)
61
+ 2. Creates site directories at `/srv/sum/<name>/`
62
+ 3. Provisions PostgreSQL database and user
63
+ 4. Scaffolds Django/Wagtail project from boilerplate
64
+ 5. Creates virtualenv and installs dependencies
65
+ 6. Runs database migrations
66
+ 7. Seeds initial homepage content
67
+ 8. Creates Django superuser
68
+ 9. Collects static files
69
+ 10. Installs systemd service
70
+ 11. Configures Caddy reverse proxy
71
+ 12. Starts the site service
72
+ 13. Optionally creates Git repository (GitHub or Gitea)
73
+
74
+ #### Options
75
+
76
+ | Flag | Description |
77
+ |------|-------------|
78
+ | `--theme <slug>` | Theme to use (default: theme_a) |
79
+ | `--profile <name>` | Content profile to seed (default: starter) |
80
+ | `--content-path <path>` | Path to custom content directory for seeding |
81
+ | `--no-git` | Skip git initialization and repository creation |
82
+ | `--skip-systemd` | Skip systemd service installation |
83
+ | `--skip-caddy` | Skip Caddy reverse proxy configuration |
84
+ | `--superuser <username>` | Custom superuser username (default: admin) |
85
+
86
+ #### Examples
87
+
88
+ **Create site with default theme:**
89
+ ```bash
90
+ sudo sum-platform init acme
91
+ ```
92
+
93
+ **Create site with specific theme:**
94
+ ```bash
95
+ sudo sum-platform init acme --theme theme_b
96
+ ```
97
+
98
+ **Create site with custom content profile:**
99
+ ```bash
100
+ sudo sum-platform init acme --profile sage-stone
101
+ ```
102
+
103
+ **Create site with external content directory:**
104
+ ```bash
105
+ sudo sum-platform init acme --content-path /path/to/profiles/acme
106
+ ```
107
+
108
+ **Create site without git/GitHub:**
109
+ ```bash
110
+ sudo sum-platform init acme --no-git
111
+ ```
112
+
113
+ **Create site with custom superuser:**
114
+ ```bash
115
+ sudo sum-platform init acme --superuser markadmin
116
+ ```
117
+
118
+ #### Output
119
+
120
+ On success:
121
+ ```
122
+ Checking infrastructure prerequisites...
123
+ ✓ Running as root
124
+ ✓ PostgreSQL available
125
+ ✓ Git available
126
+ ✓ systemctl available
127
+ ⚠ GitHub CLI not available (git operations will be skipped)
128
+
129
+ Creating site 'acme'...
130
+ [1/17] Checking prerequisites
131
+ [2/17] Generating credentials
132
+ [3/17] Creating directories
133
+ ...
134
+ [17/17] Writing credentials file
135
+
136
+ ✅ Site 'acme' created successfully!
137
+
138
+ Site Information:
139
+ Domain: acme.lintel.site
140
+ Admin URL: https://acme.lintel.site/admin/
141
+ Credentials: /srv/sum/acme/.credentials
142
+
143
+ Superuser Credentials:
144
+ Username: admin
145
+ Password: <generated>
146
+ ```
147
+
148
+ #### Directory Structure
149
+
150
+ After init, the site directory contains:
151
+
152
+ ```
153
+ /srv/sum/acme/
154
+ ├── app/ # Django project
155
+ │ ├── manage.py
156
+ │ ├── acme/ # Python package
157
+ │ ├── theme/ # Active theme
158
+ │ └── ...
159
+ ├── venv/ # Python virtualenv
160
+ ├── static/ # Collected static files
161
+ ├── media/ # User uploads
162
+ ├── backups/ # Database backups
163
+ ├── .env # Environment variables
164
+ └── .credentials # Superuser credentials
165
+ ```
166
+
167
+ ---
168
+
169
+ ### `sum-platform update` - Update a Deployed Site
170
+
171
+ Pull latest code, run migrations, and restart services.
172
+
173
+ #### Basic Usage
174
+
175
+ ```bash
176
+ sum-platform update <site-name> [options]
177
+ ```
178
+
179
+ #### What Update Does
180
+
181
+ 1. Pulls latest code from git repository
182
+ 2. Updates pip dependencies
183
+ 3. Runs database migrations (unless skipped)
184
+ 4. Collects static files
185
+ 5. Restarts systemd service
186
+
187
+ #### Options
188
+
189
+ | Flag | Description |
190
+ |------|-------------|
191
+ | `--target <env>` | Target environment: staging (default) or prod |
192
+ | `--skip-migrations` | Skip database migrations |
193
+
194
+ #### Examples
195
+
196
+ **Update staging site:**
197
+ ```bash
198
+ sum-platform update acme
199
+ ```
200
+
201
+ **Update production site (via SSH):**
202
+ ```bash
203
+ sum-platform update acme --target prod
204
+ ```
205
+
206
+ **Update without migrations:**
207
+ ```bash
208
+ sum-platform update acme --skip-migrations
209
+ ```
210
+
211
+ #### Output
212
+
213
+ ```
214
+ Updating site 'acme' on staging...
215
+ [1/5] Pulling latest code
216
+ [2/5] Installing dependencies
217
+ [3/5] Running migrations
218
+ [4/5] Collecting static files
219
+ [5/5] Restarting service
220
+
221
+ ✅ Site 'acme' updated successfully!
222
+ ```
223
+
224
+ ---
225
+
226
+ ### `sum-platform backup` - Backup a Site
227
+
228
+ Create database and optional media backups.
229
+
230
+ #### Basic Usage
231
+
232
+ ```bash
233
+ sum-platform backup <site-name> [options]
234
+ ```
235
+
236
+ #### What Backup Does
237
+
238
+ 1. Creates timestamped database dump (pg_dump | gzip)
239
+ 2. Optionally archives media directory (tar)
240
+ 3. Stores backups in `/srv/sum/<name>/backups/`
241
+
242
+ #### Options
243
+
244
+ | Flag | Description |
245
+ |------|-------------|
246
+ | `--target <env>` | Target environment: staging (default) or prod |
247
+ | `--include-media` | Include media directory in backup |
248
+
249
+ #### Examples
250
+
251
+ **Backup database only:**
252
+ ```bash
253
+ sum-platform backup acme
254
+ ```
255
+
256
+ **Backup database and media:**
257
+ ```bash
258
+ sum-platform backup acme --include-media
259
+ ```
260
+
261
+ **Backup production site:**
262
+ ```bash
263
+ sum-platform backup acme --target prod
264
+ ```
265
+
266
+ #### Output
267
+
268
+ ```
269
+ Creating backup for site 'acme'...
270
+ [1/2] Backing up database
271
+ [2/2] Backing up media
272
+
273
+ ✅ Backup completed!
274
+
275
+ Backup files:
276
+ Database: /srv/sum/acme/backups/acme_db_20260201_143022.sql.gz
277
+ Media: /srv/sum/acme/backups/acme_media_20260201_143022.tar.gz
278
+ ```
279
+
280
+ ---
281
+
282
+ ### `sum-platform promote` - Promote to Production
283
+
284
+ Deploy a staging site to a production server.
285
+
286
+ #### Basic Usage
287
+
288
+ ```bash
289
+ sum-platform promote <site-name> --domain <domain>
290
+ ```
291
+
292
+ #### What Promote Does
293
+
294
+ 1. Validates staging site exists
295
+ 2. Creates backup of staging database
296
+ 3. Copies backup to production server via SCP
297
+ 4. Provisions production infrastructure via SSH:
298
+ - Creates directories
299
+ - Provisions PostgreSQL database
300
+ - Clones git repository
301
+ - Creates virtualenv and installs dependencies
302
+ - Restores database from backup
303
+ - Syncs media files via rsync
304
+ - Installs systemd service
305
+ - Configures Caddy
306
+ - Starts service
307
+ 5. Verifies site health
308
+
309
+ #### Options
310
+
311
+ | Flag | Description |
312
+ |------|-------------|
313
+ | `--domain <domain>` | **Required.** Production domain name |
314
+
315
+ #### Examples
316
+
317
+ **Promote to production:**
318
+ ```bash
319
+ sum-platform promote acme --domain acme.example.com
320
+ ```
321
+
322
+ #### Output
323
+
324
+ ```
325
+ Promoting site 'acme' to production...
326
+ [1/11] Validating staging site
327
+ [2/11] Creating staging backup
328
+ [3/11] Copying backup to production
329
+ [4/11] Provisioning production directories
330
+ [5/11] Creating production database
331
+ [6/11] Cloning repository
332
+ [7/11] Setting up virtualenv
333
+ [8/11] Restoring database
334
+ [9/11] Syncing media
335
+ [10/11] Installing services
336
+ [11/11] Verifying health
337
+
338
+ ✅ Site promoted to production!
339
+
340
+ Production URL: https://acme.example.com
341
+ Admin URL: https://acme.example.com/admin/
342
+ ```
343
+
344
+ ---
345
+
346
+ ### `sum-platform check` - Validate Project Setup
347
+
348
+ Validate that a project is properly configured.
349
+
350
+ #### Basic Usage
351
+
352
+ ```bash
353
+ sum-platform check [project-name]
354
+ ```
355
+
356
+ #### What Check Validates
357
+
358
+ | Check | Description |
359
+ |-------|-------------|
360
+ | Virtualenv | `.venv` or `venv/` directory exists with required packages |
361
+ | Credentials | `.env.local` or `.credentials` file exists |
362
+ | Database | Migrations are up to date |
363
+ | Homepage | Default site root page configured |
364
+ | Theme CSS | Compiled CSS exists and is valid |
365
+ | Theme Slug | Theme slug matches configuration |
366
+ | Env Vars | Required environment variables present |
367
+ | sum_core | Core module can be imported |
368
+
369
+ #### Output
370
+
371
+ ```
372
+ [OK] Virtualenv: venv exists with required packages
373
+ [OK] Credentials: .credentials found
374
+ [OK] Database: Migrations up to date
375
+ [OK] Homepage: Homepage set as site root
376
+ [OK] Theme compiled CSS: /srv/sum/acme/app/theme/active/static/theme_a/css/main.css
377
+ [OK] Theme slug match: theme_a
378
+ [OK] Required env vars: Required env vars present
379
+ [OK] sum_core import: sum_core importable
380
+
381
+ ✅ All checks passed
382
+ ```
383
+
384
+ ---
385
+
386
+ ### `sum-platform themes` - List Available Themes
387
+
388
+ List all themes available in the registry.
389
+
390
+ #### Usage
391
+
392
+ ```bash
393
+ sum-platform themes
394
+ ```
395
+
396
+ #### Output
397
+
398
+ ```
399
+ Available themes:
400
+
401
+ theme_a
402
+ Name: Theme A
403
+ Description: Default starter theme
404
+ Version: 1.0.0
405
+
406
+ theme_b
407
+ Name: Theme B
408
+ Description: Alternate theme
409
+ Version: 1.2.0
410
+ ```
411
+
412
+ ---
413
+
414
+ ### `sum-platform run` - Start Development Server
415
+
416
+ Start a local development server for testing.
417
+
418
+ #### Usage
419
+
420
+ ```bash
421
+ sum-platform run [project-name] [options]
422
+ ```
423
+
424
+ #### Options
425
+
426
+ | Flag | Description |
427
+ |------|-------------|
428
+ | `--port <port>` | Port to run on (default: 8000) |
429
+
430
+ #### Examples
431
+
432
+ **Run with default port:**
433
+ ```bash
434
+ sum-platform run acme
435
+ ```
436
+
437
+ **Run on specific port:**
438
+ ```bash
439
+ sum-platform run acme --port 8080
440
+ ```
441
+
442
+ ---
443
+
444
+ ## Configuration
445
+
446
+ ### System Configuration
447
+
448
+ The CLI reads configuration from `/etc/sum/config.yml`. All fields are required.
449
+
450
+ ```yaml
451
+ agency:
452
+ # Your agency/organization name
453
+ name: "Lintel Digital"
454
+ # Git provider: "github" (default) or "gitea"
455
+ git_provider: "github"
456
+ # GitHub organization (required when git_provider: github)
457
+ github_org: "lintel-digital"
458
+ # Gitea settings (required when git_provider: gitea)
459
+ # gitea_url: "https://gitea.example.com"
460
+ # gitea_org: "lintel"
461
+ # gitea_token_env: "GITEA_TOKEN" # env var name containing API token
462
+
463
+ staging:
464
+ # Staging server hostname (for reference)
465
+ server: "staging.lintel.site"
466
+ # Domain pattern for staging sites ({slug} will be replaced)
467
+ domain_pattern: "{slug}.lintel.site"
468
+ # Base directory for site deployments
469
+ base_dir: "/srv/sum"
470
+
471
+ production:
472
+ # Production server hostname
473
+ server: "prod.lintel.site"
474
+ # SSH host for production deployments
475
+ ssh_host: "10.0.0.1"
476
+ # Base directory on production server
477
+ base_dir: "/srv/sum"
478
+
479
+ templates:
480
+ # Directory containing infrastructure templates
481
+ dir: "/opt/lintel-ops/infra"
482
+ # Relative path to systemd service template
483
+ systemd: "systemd/sum-site-gunicorn.service.template"
484
+ # Relative path to Caddy config template
485
+ caddy: "caddy/Caddyfile.template"
486
+
487
+ defaults:
488
+ # Default theme for new sites
489
+ theme: "theme_a"
490
+ # User to run site services as
491
+ deploy_user: "deploy"
492
+ # Default content seeding profile
493
+ seed_profile: "starter"
494
+ ```
495
+
496
+ ### Gitea Configuration
497
+
498
+ To use Gitea instead of GitHub:
499
+
500
+ 1. Set `git_provider: "gitea"` in the config
501
+ 2. Provide `gitea_url` and `gitea_org`
502
+ 3. Set the `GITEA_TOKEN` environment variable (or custom env var name via `gitea_token_env`)
503
+ 4. Install with Gitea support: `pip install sum-cli[gitea]`
504
+
505
+ Example Gitea configuration:
506
+
507
+ ```yaml
508
+ agency:
509
+ name: "Acme Agency"
510
+ git_provider: "gitea"
511
+ gitea_url: "https://git.acme.internal"
512
+ gitea_org: "acme-sites"
513
+ gitea_token_env: "GITEA_TOKEN"
514
+ ```
515
+
516
+ ### Environment Variables
517
+
518
+ Sites use `.env` files for configuration:
519
+
520
+ ```bash
521
+ # Database
522
+ DJANGO_DB_NAME=acme_db
523
+ DJANGO_DB_USER=acme_user
524
+ DJANGO_DB_PASSWORD=<generated>
525
+ DJANGO_DB_HOST=localhost
526
+ DJANGO_DB_PORT=5432
527
+
528
+ # Django
529
+ DJANGO_SECRET_KEY=<generated>
530
+ DJANGO_SETTINGS_MODULE=acme.settings.production
531
+
532
+ # Site
533
+ ALLOWED_HOSTS=acme.lintel.site
534
+ ```
535
+
536
+ ---
537
+
538
+ ## Prerequisites
539
+
540
+ ### For `init` command
541
+
542
+ - **Root access** (sudo)
543
+ - **PostgreSQL** server running
544
+ - **Git** installed
545
+ - **systemctl** available (systemd)
546
+ - **Caddy** installed (for reverse proxy)
547
+ - **GitHub CLI** (optional, for GitHub repository creation)
548
+ - **GITEA_TOKEN** env var (optional, for Gitea repository creation)
549
+
550
+ ### For `promote` command
551
+
552
+ - **SSH access** to production server
553
+ - **rsync** installed on both servers
554
+ - Production server with same prerequisites as staging
555
+
556
+ ---
557
+
558
+ ## Troubleshooting
559
+
560
+ ### "This command requires root privileges"
561
+
562
+ Run the command with sudo:
563
+ ```bash
564
+ sudo sum-platform init acme
565
+ ```
566
+
567
+ ### "PostgreSQL not available"
568
+
569
+ Ensure PostgreSQL is running:
570
+ ```bash
571
+ sudo systemctl start postgresql
572
+ sudo systemctl status postgresql
573
+ ```
574
+
575
+ ### "Site already exists"
576
+
577
+ The site directory already exists at `/srv/sum/<name>/`. Either:
578
+ - Choose a different name
579
+ - Remove the existing site directory (carefully!)
580
+
581
+ ### "GitHub CLI not available"
582
+
583
+ Install the GitHub CLI:
584
+ ```bash
585
+ # Ubuntu/Debian
586
+ sudo apt install gh
587
+
588
+ # Then authenticate
589
+ gh auth login
590
+ ```
591
+
592
+ Or use `--no-git` to skip GitHub operations.
593
+
594
+ ### "Gitea API token not found"
595
+
596
+ Set the token environment variable:
597
+ ```bash
598
+ export GITEA_TOKEN="your-gitea-api-token"
599
+ ```
600
+
601
+ Or use `--no-git` to skip Gitea operations.
602
+
603
+ ### Database connection errors
604
+
605
+ Check PostgreSQL configuration:
606
+ ```bash
607
+ sudo -u postgres psql -c "SELECT 1"
608
+ ```
609
+
610
+ Verify the database was created:
611
+ ```bash
612
+ sudo -u postgres psql -c "\\l" | grep acme
613
+ ```
614
+
615
+ ---
616
+
617
+ ## Migration from CLI v2
618
+
619
+ ### Key Changes
620
+
621
+ - **No more `clients/` scaffolding** - Sites are created at `/srv/sum/<name>/`
622
+ - **No more `--full` or `--quick`** - Init always does full provisioning
623
+ - **Requires sudo** - Init provisions infrastructure that requires root
624
+ - **New commands** - `update`, `backup`, `promote` for site lifecycle
625
+ - **System config** - Configuration read from `/etc/sum/config.yml`
626
+ - **Git provider choice** - Support for both GitHub and Gitea
627
+
628
+ ### Deprecated Flags
629
+
630
+ These flags from v2 are no longer supported:
631
+
632
+ - `--full`, `--quick` - Replaced by always-full provisioning
633
+ - `--no-prompt`, `--ci` - Init is now non-interactive by default
634
+ - `--skip-venv`, `--skip-migrations` - These steps are mandatory
635
+ - `--run`, `--port` - Server is started via systemd, not manually
636
+
637
+ ### Project Structure Changes
638
+
639
+ **v2 (clients/ scaffolding):**
640
+ ```
641
+ clients/acme/
642
+ ├── .venv/
643
+ ├── manage.py
644
+ └── acme/
645
+ ```
646
+
647
+ **v3 (production sites):**
648
+ ```
649
+ /srv/sum/acme/
650
+ ├── app/
651
+ │ ├── manage.py
652
+ │ └── acme/
653
+ ├── venv/
654
+ ├── static/
655
+ ├── media/
656
+ └── backups/
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Support
662
+
663
+ - **Issues:** [GitHub Issues](https://github.com/markashton480/sum-platform/issues)
sum/exceptions.py ADDED
@@ -0,0 +1,45 @@
1
+ """CLI-specific exception hierarchy.
2
+
3
+ All CLI exceptions inherit from SumCliError for consistent catching.
4
+ ThemeValidationError also inherits ValueError for compatibility with
5
+ validation patterns that expect ValueError subclasses.
6
+ """
7
+
8
+
9
+ class SumCliError(Exception):
10
+ """Base exception for SUM CLI failures."""
11
+
12
+
13
+ class SetupError(SumCliError):
14
+ """Raised when initial setup steps fail."""
15
+
16
+
17
+ class ThemeNotFoundError(SumCliError):
18
+ """Raised when a requested theme slug cannot be found."""
19
+
20
+
21
+ class ThemeValidationError(SumCliError, ValueError):
22
+ """Raised when theme exists but is invalid (bad manifest or missing files).
23
+
24
+ Inherits ValueError for compatibility with validation error handling patterns.
25
+ """
26
+
27
+
28
+ class VenvError(SumCliError):
29
+ """Raised when virtual environment operations fail."""
30
+
31
+
32
+ class DependencyError(SumCliError):
33
+ """Raised when dependency installation or resolution fails."""
34
+
35
+
36
+ class MigrationError(SumCliError):
37
+ """Raised when database migrations fail."""
38
+
39
+
40
+ class SeedError(SumCliError):
41
+ """Raised when seed data operations fail."""
42
+
43
+
44
+ class SuperuserError(SumCliError):
45
+ """Raised when superuser creation fails."""
sum/setup/__init__.py ADDED
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from sum.setup.auth import SuperuserManager
4
+ from sum.setup.database import DatabaseManager
5
+ from sum.setup.deps import DependencyManager
6
+ from sum.setup.orchestrator import SetupOrchestrator
7
+ from sum.setup.seed import ContentSeeder
8
+ from sum.setup.venv import VenvManager
9
+
10
+ __all__ = [
11
+ "ContentSeeder",
12
+ "DatabaseManager",
13
+ "DependencyManager",
14
+ "SetupOrchestrator",
15
+ "SuperuserManager",
16
+ "VenvManager",
17
+ ]