Root now contains only essential files: README.md, CLAUDE.md, CHANGELOG.md, CONTRIBUTING.md Reorganized into: docs/audits/ — all audit reports & checklists (71 files) docs/architecture/ — codebase overview, implementation plan docs/guides/ — auth guide, implementation checklist docs/load-testing/ — k6 load test guides & endpoints docs/security/ — payment & security reviews Also removed 5 untracked debug/investigation files and cleaned up playwright-report/ & test-results/ artifacts. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
486 lines
18 KiB
Markdown
486 lines
18 KiB
Markdown
# GoodGo Platform AI — Production Readiness Assessment
|
|
**Date:** April 12, 2026
|
|
**Project Location:** `/Users/velikho/Desktop/WORKING/goodgo-platform-ai/`
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
The GoodGo Platform AI project has **MODERATE production readiness**. Core infrastructure (CI/CD, monitoring, backup/restore) is well-documented and partially implemented. However, several critical production items are **incomplete or untested in production**.
|
|
|
|
**Key Gaps:**
|
|
- SSL/TLS and DNS configuration not deployed (templates only)
|
|
- Penetration testing/security audit not completed
|
|
- CDN setup for static assets not configured
|
|
- E2E test results show failures
|
|
- Performance benchmarks only at framework level (not business logic)
|
|
|
|
---
|
|
|
|
## Detailed Assessment: 12 Items
|
|
|
|
### ✅ **1. Load Testing Results** — MODERATE
|
|
**Status:** Scripts exist with baseline results documented
|
|
**Evidence:**
|
|
- **Path:** `/load-tests/` directory
|
|
- `scripts/` contains K6 test files: `auth.js`, `listings.js`, `search.js`, `search-advanced.js`, `admin.js`, `mcp.js`, `payments.js`
|
|
- `results/BASELINE-REPORT.md` — comprehensive baseline report dated 2026-04-09
|
|
- `results/` contains JSON output files: `auth.json`, `listings.json`, `search.json`, `payments.json`
|
|
|
|
**What Exists:**
|
|
- ✅ K6 load test suite with 7 test scripts
|
|
- ✅ SLA thresholds defined (p50 < 200ms, p95 < 500ms, p99 < 1s, error rate < 1%)
|
|
- ✅ Baseline results documented with detailed metrics
|
|
- ✅ CI integration via `.github/workflows/load-test.yml`
|
|
|
|
**What's Missing:**
|
|
- ❌ Production environment test results (only local dev baseline)
|
|
- ❌ Performance regression tracking (should be CI gated)
|
|
- ❌ Historical trend data (no time-series analysis)
|
|
- ❌ Grafana/InfluxDB integration for visualization
|
|
|
|
**Status Notes:**
|
|
Baseline shows framework-level performance is excellent (p95 latencies < 6ms), but business logic validation blocked by dev environment limitations. Auth and payment endpoints return 500 errors; Typesense unavailable. Recommends re-running against staging with full dependencies.
|
|
|
|
---
|
|
|
|
### ❌ **2. Security Penetration Test Sign-Off** — MISSING
|
|
**Status:** No formal penetration test or security audit sign-off found
|
|
**Evidence:**
|
|
- **Path:** `/docs/audits/` contains accessibility and architecture audits, but NO security/penetration testing
|
|
- **CI Security:** `.github/workflows/security.yml` exists with:
|
|
- Dependency audit (pnpm)
|
|
- Container scanning (Trivy)
|
|
- CodeQL SAST analysis
|
|
- No DAST/pen-test integration
|
|
|
|
**What Exists:**
|
|
- ✅ Automated dependency vulnerability scanning (pnpm audit, runs on schedule)
|
|
- ✅ Container image scanning (Trivy) for API, Web, AI-services images
|
|
- ✅ Code scanning (CodeQL) for source code vulnerabilities
|
|
- ✅ Security checklist in `docs/deployment.md` (incomplete)
|
|
|
|
**What's Missing:**
|
|
- ❌ Third-party penetration test report
|
|
- ❌ OWASP Top 10 assessment
|
|
- ❌ Security audit sign-off document
|
|
- ❌ API security testing (DAST)
|
|
- ❌ Web application security scan
|
|
- ❌ Infrastructure security audit
|
|
|
|
**Recommendation:** Schedule formal pen-test before production launch.
|
|
|
|
---
|
|
|
|
### ✅ **3. Monitoring Alert Thresholds Configured** — GOOD
|
|
**Status:** Comprehensive alert rules defined and configured
|
|
**Evidence:**
|
|
- **Path:** `/monitoring/prometheus/alert-rules.yml` (15,969 bytes)
|
|
- Alert groups defined: `goodgo_api_latency`, `goodgo_database`, `goodgo_redis`, `goodgo_infra`
|
|
- Per-rule thresholds with severity labels
|
|
- Dashboard links and runbook URLs embedded
|
|
|
|
**Specific Alerts Configured:**
|
|
- API latency: p99 > 1s (warning), > 3s (critical)
|
|
- Per-endpoint latency: p99 > 2s
|
|
- 5xx error rate: > 1% for 5 minutes
|
|
- Database: connection pool exhaustion, high query latency
|
|
- Redis: connection failures, high memory
|
|
- Infrastructure: disk space, CPU, memory alerts
|
|
|
|
**What Exists:**
|
|
- ✅ 15+ alerting rules across API, database, cache, infrastructure
|
|
- ✅ Alert severity labels (warning, critical)
|
|
- ✅ Runbook URLs and dashboard links in annotations
|
|
- ✅ AlertManager configured (`monitoring/alertmanager/alertmanager.yml`)
|
|
- ✅ Prometheus scraping configured (`monitoring/prometheus/prometheus.yml`)
|
|
- ✅ Grafana provisioned with datasources
|
|
|
|
**What's Missing:**
|
|
- ❌ Alert routing/notification channels not visible (Slack, PagerDuty, email) — likely in secrets
|
|
- ❌ No baseline testing of alert triggers
|
|
- ❌ No alert tuning documentation (what thresholds are based on)
|
|
|
|
---
|
|
|
|
### ✅ **4. Backup/Restore Verification** — GOOD
|
|
**Status:** Backup procedures documented; automated verification in place
|
|
**Evidence:**
|
|
- **Path:** `/docs/backup-restore.md` (comprehensive guide, 251 lines)
|
|
- **Path:** `.github/workflows/backup-verify.yml` (automated weekly verification)
|
|
|
|
**Backup Strategy:**
|
|
- PostgreSQL: Daily at 02:00 UTC via `pg-backup` container (`pg_dump` custom format, compression level 6)
|
|
- Redis: AOF persistence + optional RDB snapshots
|
|
- Typesense: Built-in snapshot API + volume backup
|
|
- Retention: 7 days (default)
|
|
- RTO: ~15 min (local backup), ~30 min (off-site)
|
|
- RPO: ≤ 24 hours
|
|
|
|
**What Exists:**
|
|
- ✅ Automated backup procedures (cron-based in docker-compose.prod.yml)
|
|
- ✅ Restore procedures documented with step-by-step instructions
|
|
- ✅ Disaster recovery runbook (4 scenarios: DB failure, service crash, full host, data corruption)
|
|
- ✅ Backup verification workflow (GitHub Actions, runs weekly)
|
|
- ✅ Backup integrity checks (`pg_restore --list`)
|
|
- ✅ All three data stores covered (PostgreSQL, Redis, Typesense)
|
|
|
|
**What's Missing:**
|
|
- ⚠️ Off-site backup storage not documented (where backups are sent)
|
|
- ❌ No tested restore from off-site backup
|
|
- ❌ No documented backup retention policy for off-site storage
|
|
- ⚠️ WAL archiving for point-in-time recovery not mentioned
|
|
|
|
---
|
|
|
|
### ✅ **5. Incident Response Runbook** — GOOD
|
|
**Status:** Comprehensive runbook exists
|
|
**Evidence:**
|
|
- **Path:** `/docs/RUNBOOK.md` (41,441 bytes, last updated 2026-04-11)
|
|
|
|
**Runbook Contents:**
|
|
1. Service Inventory (17 services listed with resource limits, health checks)
|
|
2. Health Checks (application endpoints, verification procedures)
|
|
3. Common Incidents (10 scenarios):
|
|
- 3.1: Database connection pool exhaustion
|
|
- 3.2: Redis connection failure
|
|
- 3.3: Typesense unavailable
|
|
- 3.4: High API latency
|
|
- 3.5: Payment callback failures
|
|
- 3.6: Disk space alerts
|
|
- 3.7: MinIO / Object storage failure
|
|
- 3.8: AI services unavailable
|
|
- 3.9: Log pipeline failure
|
|
- 3.10: 5xx error rate spike
|
|
4. Recovery Procedures (5 detailed procedures)
|
|
5. Escalation Matrix
|
|
6. Monitoring Dashboards
|
|
7. Useful PromQL Queries
|
|
8. Environment Quick Reference
|
|
|
|
**What Exists:**
|
|
- ✅ Complete incident response procedures (10+ scenarios)
|
|
- ✅ Step-by-step recovery procedures
|
|
- ✅ Health check commands
|
|
- ✅ Service dependency diagram
|
|
- ✅ Escalation contacts and matrix
|
|
- ✅ PromQL query examples for troubleshooting
|
|
|
|
**What's Missing:**
|
|
- ⚠️ Escalation matrix not fully visible (contact numbers/Slack channels likely redacted)
|
|
- ❌ No incident log/post-mortem template
|
|
- ❌ No tested drills/runbook exercises
|
|
|
|
---
|
|
|
|
### ✅ **6. Database Schema Frozen (Migration Lockdown)** — GOOD (Partial)
|
|
**Status:** Migrations exist and organized; migration locking mechanism in place
|
|
**Evidence:**
|
|
- **Path:** `/prisma/migrations/` (16 migration directories)
|
|
- **Path:** `/prisma/migrations/migration_lock.toml`
|
|
|
|
**Migrations:**
|
|
```
|
|
20260407165528_init
|
|
20260407210149_add_missing_fk_indexes
|
|
20260408000000_add_idempotency_key_to_payment
|
|
20260408061200_fix_schema_integrity
|
|
20260408080000_add_analytics_media_quota_fields
|
|
20260408160000_add_review_userid_index
|
|
20260409000000_add_notification_read_at
|
|
20260409100000_add_compound_indexes_query_optimization
|
|
20260409120000_add_missing_query_indexes
|
|
20260410000000_add_user_soft_delete_fields
|
|
20260410100000_add_admin_audit_log
|
|
20260411000000_add_cascade_delete_strategies
|
|
20260411100000_add_pii_encryption_hash_columns
|
|
20260411200000_add_mfa_totp_support (most recent)
|
|
```
|
|
|
|
**What Exists:**
|
|
- ✅ Migration lock file (`migration_lock.toml`) — prevents provider changes
|
|
- ✅ 16 sequential migrations from 2026-04-07 to 2026-04-11 (recent activity)
|
|
- ✅ CI integration: `pnpm db:migrate:deploy` in GitHub Actions (read-only)
|
|
- ✅ Direct database connection separate from PgBouncer (required for DDL)
|
|
|
|
**What's Missing:**
|
|
- ⚠️ No documented freeze procedure (how to prevent migrations in production lockdown)
|
|
- ❌ No "production schema freeze" documentation
|
|
- ❌ No tested rollback procedures
|
|
|
|
**Status Notes:**
|
|
Schema is currently NOT frozen — migrations are active. Recent migrations added encryption, MFA, audit logging. For true production lockdown, would need explicit "no migrations" policy + CI enforcement.
|
|
|
|
---
|
|
|
|
### ✅ **7. CI/CD Pipeline** — GOOD
|
|
**Status:** Comprehensive CI/CD pipeline configured
|
|
**Evidence:**
|
|
- **Path:** `.github/workflows/` (9 workflow files)
|
|
|
|
**Workflows:**
|
|
1. **ci.yml** — Main CI: Lint → Typecheck → Test → Build → E2E (on ubuntu-latest, Node 22)
|
|
- Services: PostgreSQL (postgis:16-3.4), Redis, Typesense, MinIO
|
|
- Steps: pnpm install → lint → typecheck → test → build → e2e
|
|
- E2E uploads Playwright reports as artifacts
|
|
|
|
2. **e2e.yml** — Separate E2E workflow (deprecated, ci.yml combines)
|
|
- API + Web E2E tests
|
|
- Artifact uploads
|
|
|
|
3. **deploy.yml** — Deployment pipeline
|
|
- Build & push Docker images to GHCR
|
|
- Deploy to staging/production (structure visible)
|
|
|
|
4. **load-test.yml** — K6 load testing
|
|
- Manual trigger (workflow_dispatch)
|
|
- Runs against custom API URL
|
|
|
|
5. **security.yml** — Security scanning
|
|
- Dependency audit (pnpm)
|
|
- Container scanning (Trivy) for API, Web, AI-services
|
|
- CodeQL SAST analysis
|
|
- Runs on push, PR, and daily schedule (05:43 UTC)
|
|
|
|
6. **backup-verify.yml** — Automated backup verification
|
|
- Weekly schedule (Sundays 05:00 UTC)
|
|
- Manual trigger
|
|
- Creates backup and runs verification script
|
|
|
|
7. **codeql.yml** — CodeQL analysis (standard template)
|
|
|
|
**What Exists:**
|
|
- ✅ Full CI pipeline: lint, typecheck, test, build
|
|
- ✅ E2E testing in CI with artifact uploads
|
|
- ✅ Separate security scanning workflow
|
|
- ✅ Load testing workflow (manual trigger)
|
|
- ✅ Backup verification workflow (weekly)
|
|
- ✅ Docker image building and pushing to GHCR
|
|
- ✅ Concurrency controls to prevent duplicate runs
|
|
- ✅ Service health checks (PostgreSQL, Redis, Typesense, MinIO)
|
|
|
|
**What's Missing:**
|
|
- ❌ No visible CD (continuous deployment) stage — deploy.yml exists but configuration unclear
|
|
- ⚠️ No SLA gating in CI (e.g., fail if p95 latency > 500ms)
|
|
- ❌ No integration tests between services
|
|
- ❌ No performance regression testing in CI
|
|
|
|
---
|
|
|
|
### ⚠️ **8. E2E Test Results** — MODERATE
|
|
**Status:** Test suite exists; recent results show failures
|
|
**Evidence:**
|
|
- **Path:** `/e2e/` directory (comprehensive E2E test suite)
|
|
- API tests: 16 spec files (auth, listings, search, payments, admin, etc.)
|
|
- Web tests: 17 spec files (UI scenarios)
|
|
- Fixtures and global setup/teardown
|
|
|
|
**Test Files:**
|
|
- `/e2e/api/admin.spec.ts`, `auth-*.spec.ts`, `inquiries.spec.ts`, `listings*.spec.ts`, `mcp.spec.ts`, `payments*.spec.ts`, `search.spec.ts`, `subscriptions.spec.ts`
|
|
- `/e2e/web/` — Playwright web UI tests
|
|
|
|
**Recent Results:**
|
|
- **Report:** `playwright-report/` (generated 2026-04-11 21:46)
|
|
- **Status:** FAILED (`.last-run.json` shows 2 failed tests)
|
|
- **Failed Tests:**
|
|
- `72b40b5065e5b60fb5e0-af881f611f09a33bace0`
|
|
- `72b40b5065e5b60fb5e0-dbc0ed94115981ddb54c`
|
|
|
|
**What Exists:**
|
|
- ✅ Comprehensive E2E test suite (33+ spec files)
|
|
- ✅ Playwright HTML report generated
|
|
- ✅ Global fixtures (user creation, database seeding)
|
|
- ✅ CI integration (runs after unit tests pass)
|
|
- ✅ Artifact uploads (reports retained 14 days, traces 7 days)
|
|
- ✅ playwright.config.ts configured
|
|
|
|
**What's Missing:**
|
|
- ❌ Test failure details not documented (need to inspect report)
|
|
- ❌ Flaky test analysis
|
|
- ❌ Test coverage metrics
|
|
- ❌ SLA validation in E2E tests
|
|
|
|
**Status Notes:**
|
|
E2E tests are comprehensive but currently failing. Not production-ready until failures are resolved.
|
|
|
|
---
|
|
|
|
### ❌ **9. Performance Benchmarks Documented** — MISSING
|
|
**Status:** Only framework-level baseline; no business logic benchmarks
|
|
**Evidence:**
|
|
- **Path:** `/load-tests/results/BASELINE-REPORT.md` (only baseline)
|
|
- **Path:** No dedicated performance benchmark documentation
|
|
|
|
**What Exists:**
|
|
- ✅ K6 baseline report with latency metrics (p50, p95, p99)
|
|
- ✅ Throughput metrics (RPS)
|
|
- ✅ SLA thresholds defined in load-tests/lib/config.js
|
|
|
|
**What's Missing:**
|
|
- ❌ No documented performance baseline for production (only local dev)
|
|
- ❌ No per-endpoint performance targets
|
|
- ❌ No database query performance benchmarks
|
|
- ❌ No API response time budgets
|
|
- ❌ No historical performance tracking
|
|
- ❌ No performance regression detection
|
|
|
|
**Status Notes:**
|
|
Load tests blocked by database/dependency issues. Framework responds in < 10ms, but business logic latency unknown.
|
|
|
|
---
|
|
|
|
### ❌ **10. SSL/TLS Certificates** — NOT CONFIGURED
|
|
**Status:** Configuration templates exist; no production certs deployed
|
|
**Evidence:**
|
|
- **Path:** `/docker-compose.prod.yml` — no SSL/TLS configuration visible
|
|
- **Path:** `/infra/pgbouncer/pgbouncer.ini` — SSL options commented out:
|
|
```
|
|
;; client_tls_sslmode = prefer
|
|
;; client_tls_key_file = /etc/pgbouncer/tls/server.key
|
|
;; client_tls_cert_file = /etc/pgbouncer/tls/server.crt
|
|
```
|
|
- **Path:** `/docs/deployment.md` line 146:
|
|
```
|
|
- [ ] Enable SSL/TLS termination (reverse proxy)
|
|
```
|
|
|
|
**What Exists:**
|
|
- ✅ PgBouncer TLS configuration templates (commented out)
|
|
- ✅ Checklist item for SSL/TLS in deployment docs
|
|
|
|
**What's Missing:**
|
|
- ❌ No reverse proxy (nginx/ALB) configured in docker-compose.prod.yml
|
|
- ❌ No certificate provisioning mechanism (Let's Encrypt, etc.)
|
|
- ❌ No TLS termination for API/Web services
|
|
- ❌ No HSTS headers configuration
|
|
- ❌ No certificate renewal procedure documented
|
|
|
|
**Recommendation:** Deploy nginx reverse proxy with Let's Encrypt for production.
|
|
|
|
---
|
|
|
|
### ❌ **11. DNS Configuration** — NOT DOCUMENTED
|
|
**Status:** No DNS configuration found
|
|
**Evidence:**
|
|
- **Path:** No `infra/dns/` directory
|
|
- **Path:** No DNS documentation in `/docs/`
|
|
- **Path:** Deployment guide mentions "production architecture" but no DNS config
|
|
|
|
**What Exists:**
|
|
- ✅ Environment variables for API URL: `NEXT_PUBLIC_API_URL` in docker-compose.prod.yml
|
|
- ✅ Deployment architecture diagram showing load balancer
|
|
|
|
**What's Missing:**
|
|
- ❌ No DNS provider configuration (AWS Route53, Cloudflare, etc.)
|
|
- ❌ No domain/subdomain setup documentation
|
|
- ❌ No DNS health checks
|
|
- ❌ No failover DNS configuration
|
|
- ❌ No DNS security (DNSSEC)
|
|
|
|
**Recommendation:** Document DNS setup for production domains (api.goodgo.vn, goodgo.vn, etc.).
|
|
|
|
---
|
|
|
|
### ❌ **12. CDN Setup for Static Assets** — NOT CONFIGURED
|
|
**Status:** Mentioned in deployment checklist but not implemented
|
|
**Evidence:**
|
|
- **Path:** `/docs/deployment.md` line 167:
|
|
```
|
|
- [ ] Configure CDN for static assets (Next.js `/_next/static/`)
|
|
```
|
|
- **Path:** No CDN configuration in `docker-compose.prod.yml`
|
|
- **Path:** No Cloudflare/AWS CloudFront/Fastly integration visible
|
|
|
|
**What Exists:**
|
|
- ✅ Next.js app configured (compiles static assets in `/_next/static/`)
|
|
- ✅ Deployment notes mention Vercel/Cloudflare as options for Web scaling
|
|
|
|
**What's Missing:**
|
|
- ❌ No CDN provider integration (Cloudflare, AWS CloudFront, etc.)
|
|
- ❌ No cache headers configured
|
|
- ❌ No cache invalidation procedure
|
|
- ❌ No asset versioning/hashing
|
|
- ❌ No CDN routing rules
|
|
|
|
**Recommendation:** Integrate with Cloudflare or AWS CloudFront for static asset delivery.
|
|
|
|
---
|
|
|
|
## Summary Table
|
|
|
|
| Item | Status | Critical? | Evidence |
|
|
|------|--------|-----------|----------|
|
|
| 1. Load testing results | ✅ MODERATE | No | K6 baseline exists (local only) |
|
|
| 2. Security pen-test sign-off | ❌ MISSING | **YES** | No formal audit/pen-test report |
|
|
| 3. Monitoring alerts configured | ✅ GOOD | No | 15+ alert rules in prometheus |
|
|
| 4. Backup/restore verification | ✅ GOOD | No | Automated weekly verification |
|
|
| 5. Incident response runbook | ✅ GOOD | No | 41KB comprehensive runbook |
|
|
| 6. Database schema frozen | ✅ MODERATE | No | Migration lock exists, but not frozen |
|
|
| 7. CI/CD pipeline | ✅ GOOD | No | 9 workflows, full CI coverage |
|
|
| 8. E2E test results | ⚠️ FAILING | **YES** | 2 tests failing, needs investigation |
|
|
| 9. Performance benchmarks | ❌ MISSING | **YES** | Only framework-level baseline |
|
|
| 10. SSL/TLS certificates | ❌ NOT CONFIG | **YES** | No reverse proxy, no certs |
|
|
| 11. DNS configuration | ❌ MISSING | **YES** | No domain/DNS setup docs |
|
|
| 12. CDN for static assets | ❌ NOT CONFIG | No | Checklist item unchecked |
|
|
|
|
---
|
|
|
|
## Critical Blockers for Production (Must Fix)
|
|
|
|
1. **Security Audit** — Conduct penetration test before launch
|
|
2. **E2E Tests** — Fix 2 failing tests
|
|
3. **SSL/TLS Termination** — Deploy reverse proxy with valid certificates
|
|
4. **DNS Setup** — Configure production domains
|
|
5. **Performance Validation** — Run load tests against staging with full dependencies
|
|
|
|
---
|
|
|
|
## Recommendations (Priority Order)
|
|
|
|
### P0 (Blocking)
|
|
1. Schedule formal penetration test (3-4 weeks)
|
|
2. Debug and fix E2E test failures
|
|
3. Deploy nginx reverse proxy with Let's Encrypt SSL
|
|
4. Configure DNS for production domains
|
|
5. Run load tests against staging environment
|
|
|
|
### P1 (Before GA)
|
|
1. Document CDN setup (Cloudflare/CloudFront)
|
|
2. Freeze database schema (implement "no migrations in production" policy)
|
|
3. Document off-site backup storage and restore procedures
|
|
4. Create performance benchmark baselines for all endpoints
|
|
5. Add SLA validation to CI pipeline (fail if p95 > 500ms)
|
|
|
|
### P2 (Nice-to-have)
|
|
1. Implement DAST/API security scanning in CI
|
|
2. Add performance regression detection to CI
|
|
3. Set up incident log and post-mortem template
|
|
4. Document alert tuning and threshold rationale
|
|
5. Test backup recovery from off-site storage
|
|
|
|
---
|
|
|
|
## Files Reviewed
|
|
|
|
**Configuration:**
|
|
- docker-compose.prod.yml
|
|
- .github/workflows/* (9 files)
|
|
- prisma/migrations/ (16 migrations)
|
|
- monitoring/* (prometheus, grafana, alertmanager, loki, promtail)
|
|
|
|
**Documentation:**
|
|
- docs/backup-restore.md
|
|
- docs/RUNBOOK.md
|
|
- docs/deployment.md
|
|
- docs/audits/* (no security audit found)
|
|
- load-tests/results/BASELINE-REPORT.md
|
|
- K6_LOAD_TESTING_GUIDE.md
|
|
|
|
**Test Results:**
|
|
- playwright-report/ (E2E results, 2 failures)
|
|
- load-tests/results/ (auth.json, listings.json, search.json, payments.json)
|
|
|
|
---
|
|
|
|
**Generated:** 2026-04-12
|