হোম /
ভূমিকা /
প্রযুক্তি স্ট্যাক
বাংলা সারসংক্ষেপ
ব্যাকএন্ডে PHP 8.2 LTS Nginx-এ; ডেটাবেস MySQL 8.0/MariaDB; ক্যাশিং Redis; ফাইল স্টোরেজ AWS S3; ইমেইল AWS SES। ফ্রন্টএন্ড সার্ভার-রেন্ডার্ড HTML টেইলউইন্ড দিয়ে। GDS ইন্টিগ্রেশনের জন্য IttAMASearch PHP ক্লাস।
বিস্তারিত (English)
Chapter 0.4 — Technology Stack
1. Purpose
This chapter inventories every technology in travoBooks' production stack: language runtimes, frameworks, datastores, infrastructure components, libraries, observability tooling, and supporting services. It serves as the canonical reference for new engineers, security reviewers, vendor due-diligence, and operations runbooks. When a chapter elsewhere references "the cache layer" or "the queue worker", the concrete component is defined here.
2. Why it matters in modern travel accounting
Travel-accounting platforms are unusual: they combine high-volume transactional workloads (booking inserts at airline-network latency), strict financial integrity (double-entry posting must not lose a single line), and integrations with legacy XML-heavy systems (GDS, BSP, IATA portals). Stack choices are constrained by these forces — for example, the operational database and ledger must share a single ACID transaction for issuance to be safe, which is why the platform uses a relational RDBMS rather than a polyglot persistence layer.
3. Industry relevance
The stack favours boring, well-understood components over novelty. Auditors recognise MySQL and standard SQL; insurers and banking partners ask familiar questions about TLS, KMS, and DR; engineers can join the team without learning bespoke languages. Travel-tech specifically benefits from PHP's mature SOAP / XML tooling — necessary for Amadeus, Sabre, and Travelport legacy endpoints — without forcing the platform onto an obscure runtime.
4. Compliance considerations
- PCI DSS — payment card data never lands in the application DB; gateway tokens only. The stack section on cardholder-data boundary is enforced at the integration layer (see Volume 7).
- GDPR / data-protection — encryption at rest (AES-256 on EBS/S3/RDS), encryption in transit (TLS 1.2+ exclusively), key custody via cloud KMS with rotation.
- SOC 2 / ISO 27001 readiness — every stack component emits structured logs to a central WORM-retained log store; immutable audit trail is preserved for ≥7 years.
- IFRS 15 / IAS 21 enforcement at code level — the JE engine is the only path from operational state to the ledger; the stack does not expose direct SQL writes to the GL.
5. Stack inventory
5.1 Application runtime
| Component |
Version baseline |
Role |
| PHP |
8.2 LTS (8.3 supported) |
Primary application language |
| OPcache |
Bundled |
Bytecode caching |
| JIT |
Enabled (tracing mode) |
Hot-path performance |
| Composer |
2.7+ |
Dependency management |
| PHP-FPM |
Bundled |
Process manager behind Nginx |
PHP was chosen because (a) the founding team has deep PHP expertise, (b) the Amadeus / Sabre SOAP toolchain is mature in PHP, (c) hosting costs are low, and (d) the codebase already runs cleanly on PHP 8+ with strict types. Future hot paths may be extracted to compiled services but the monolith remains PHP.
5.2 Web tier
| Component |
Version |
Role |
| Nginx |
1.24+ |
Reverse proxy, TLS termination, static asset serving, rate-limiting |
| HTTP/2 |
Enabled |
Multiplexed client connections |
| Let's Encrypt / ACM |
Auto-renew |
Certificate management |
| ModSecurity (CRS 4) |
Enabled in detect mode |
WAF — moves to block mode for known attack patterns |
.htaccess style URL hiding (per platform UX preferences) is implemented by Nginx try_files rules; .php extensions never appear in client-facing URLs.
5.3 Database tier
| Component |
Version |
Role |
| MySQL |
8.0 LTS (MariaDB 10.11+ compatible) |
Primary OLTP store — all operational + ledger data |
| InnoDB |
Default engine |
ACID, row-level locking, foreign keys |
| Read replicas |
2× minimum in prod |
Reporting, search, read-heavy endpoints |
| MyDumper / mysqldump |
Nightly |
Logical backups |
| Percona XtraBackup |
Hourly incremental |
Physical backups for fast restore |
travoBooks uses a single primary database for operational + financial data. This is deliberate: it guarantees that booking issuance and journal-entry posting occur in one transaction, removing the entire class of "ledger drift" bugs that plague distributed-database designs in travel.
5.4 Cache & queue
| Component |
Version |
Role |
| Redis |
7.2+ |
Session store, permission cache, distributed locks, queue backend, idempotency-key store |
| Sentinel / Cluster |
Enabled in prod |
HA failover |
| Queue framework |
Internal travoBooks\Queue (Redis-backed) |
Async jobs — emails, GDS polling, webhooks, BSP imports |
| Cron orchestrator |
Single elected leader (Redis lock) |
Scheduled jobs (FX refresh, BSP import, dunning) |
5.5 Object storage
| Component |
Role |
| Amazon S3 (or compatible — MinIO, Wasabi) |
Documents — invoices PDF, receipts, BSP reports, supplier statements, KYC files |
| Bucket-per-partner logical layout |
travobooks-docs-prod/<partner_id>/<year>/<month>/<doc_id>.<ext> |
| Bucket policies |
Deny public read; presigned URLs only |
| Server-side encryption |
SSE-KMS with per-partner key alias |
5.6 Search
| Component |
Role |
| MySQL FULLTEXT indexes |
Phase 1 search across customers, suppliers, bookings, invoices |
| OpenSearch / Elasticsearch |
Phase 2 (planned) — high-volume cross-module search |
5.7 Email & messaging
| Component |
Role |
| AWS SES |
Transactional email (invoices, receipts, alerts) |
| PHPMailer |
SMTP client library |
| Twilio / Local SMS gateways |
OTP, critical alerts |
| Webhook delivery service |
Internal — signed HTTPS POST with retries |
5.8 Frontend
| Component |
Role |
| Server-rendered HTML (PHP templates) |
Primary UI — fast, indexable, simple |
| Tailwind CSS (custom build) |
Styling, brand colour #C7090C |
| Sora / Inter / JetBrains Mono |
Typography |
| Lucide icons |
Iconography |
| Vanilla JS + light Alpine.js |
Interactivity; no SPA framework |
| HTMX (selective) |
Partial-page updates for high-interaction screens (booking, JE entry) |
The UI uses a server-rendered, progressive-enhancement model — chosen for predictability, accessibility, low operational overhead, and because financial UIs benefit from the simplicity of submit-and-redirect patterns.
5.9 Integrations layer
| Integration |
Library / SDK |
| Amadeus GDS |
Custom IttAMASearch + SOAP client; XML parsing via DOMDocument / SimpleXMLElement |
| Sabre GDS |
REST client (Sabre OAuth2) |
| NDC offers |
REST clients per supplier (IATA NDC Level 3 schemas) |
| LCC aggregators |
REST — per aggregator schema |
| Hotel suppliers (Hotelbeds, etc.) |
REST clients |
| Payment gateways |
Stripe SDK, regional gateway SDKs (SSLCommerz, Razorpay, etc.) |
| BSP / ARC |
SFTP polling + parsing of HOT, AGTDATA, BSPLink CSV files |
| Accounting export |
QuickBooks IIF, Xero CSV, Tally XML (Phase 2) |
5.10 Observability
| Component |
Role |
| Structured JSON logs |
Every request logged with request_id, partner_id, user_id, route, duration_ms, status |
| OpenTelemetry |
Traces across HTTP / DB / Redis / queue |
| Prometheus + Grafana |
Metrics dashboards |
| Sentry (self-hosted Glitchtip option) |
Error aggregation |
| Uptime checks |
Synthetic monitoring on critical endpoints |
| Audit log (DB-backed) |
Business-event log — separate from operational logs, retained ≥7 years |
5.11 Security stack
| Component |
Role |
| Argon2id |
Password hashing, PAT hashing |
| TOTP (RFC 6238) |
Multi-factor authentication |
| WebAuthn |
Phase 2 — passkey support |
| CSP (Content-Security-Policy) |
Strict; no inline scripts in production builds |
| Cookie flags |
HttpOnly, Secure, SameSite=Strict, __Host- prefix |
| CSRF tokens |
Per-session, per-form rotating tokens |
| Rate limiting |
Nginx layer + application layer (Redis sliding window) |
| WAF |
ModSecurity CRS 4 |
| Secrets manager |
AWS Secrets Manager / HashiCorp Vault |
| KMS |
AWS KMS or compatible; key rotation enforced |
5.12 Infrastructure
| Component |
Role |
| Cloud provider |
AWS primary; portable to GCP / Azure / on-prem |
| VPC layout |
Public subnets (LB only), private subnets (app + DB), no public DB exposure |
| Application servers |
2× minimum behind ALB |
| Database |
RDS / managed MySQL (or self-managed with Percona) |
| Bastion / SSM |
Session Manager for ops access; no inbound SSH |
| CI/CD |
GitHub Actions → ECR / artifact store → blue-green deploy |
| IaC |
Terraform (preferred) or CloudFormation |
6. Module dependencies
The technology stack is the substrate for every module in the platform. No module bypasses these layers — direct database access from controllers is forbidden; all DB writes go through the persistence layer (see Volume 1), and all ledger writes go through the JE engine (see Volume 5).
flowchart TB
UI[PHP Templates + Tailwind] --> APP[PHP Application Layer]
APIClient[External API Client] --> APP
APP --> CACHE[Redis Cache]
APP --> DB[(MySQL Primary)]
APP --> QUEUE[Redis Queue]
QUEUE --> WORKERS[PHP Workers]
WORKERS --> DB
WORKERS --> S3[S3 Object Store]
WORKERS --> SES[AWS SES]
WORKERS --> GDS[GDS / NDC / LCC APIs]
DB --> REPLICA[(Read Replica)]
REPORTING[Reporting UI] --> REPLICA
OBS[OpenTelemetry / Prometheus] -.-> APP
OBS -.-> WORKERS
OBS -.-> DB
7. Security & permissions
Every stack component runs with least privilege. The application database user has DML on operational tables but no DDL; schema changes go through a separate migration user. The cache and queue Redis instances are isolated network-wise from public ingress. S3 buckets are private with KMS-managed encryption; access is scoped per partner via prefix-based IAM policies in Phase 2.
8. Validation rules (deployment checklist)
| Code |
Rule |
STACK_TLS_VERSION_BELOW_1_2 |
TLS version below 1.2 detected — deploy blocked |
STACK_DB_PUBLIC_EXPOSURE |
DB instance reachable from public subnet — deploy blocked |
STACK_KMS_KEY_ROTATION_DISABLED |
KMS key rotation not enabled — deploy blocked |
STACK_BACKUP_OLDER_THAN_24H |
No successful backup in 24h — paging alert |
STACK_REPLICA_LAG_OVER_60S |
Read replica lag > 60s — paging alert |
9. Common pitfalls (⚠️)
- ⚠️ Do not introduce a second OLTP database. Any "side store" that holds financial state becomes a reconciliation problem. Side stores are acceptable only for read-only projections (search, analytics, cache).
- ⚠️ Do not write to the ledger outside the JE engine. SQL
INSERT INTO journal_entries from a controller is a serious bug — bypasses balance check, dimension validation, period state, FX capture.
- ⚠️ Do not bypass the queue for slow integrations. Synchronous GDS calls inside a request can exceed timeouts; always queue-and-poll for long-running supplier operations.
- 🔒 PCI scope. PAN data must never enter the application database. If a feature appears to require storing PAN, route through the gateway tokenisation flow instead.
10. Future scalability
- Phase 2 — extract the read-heavy reporting layer to OpenSearch + materialised views on the replica.
- Phase 3 — move BSP / supplier-import workers to a separate cluster (Kubernetes-managed) for elastic batch scaling.
- Phase 4 — partner-id-based sharding of the primary DB when a single partner approaches 5M bookings/year or the total transaction volume exceeds the headroom of vertical scaling.
- Phase 5 — optional read-only GraphQL layer for partner-built dashboards.
The stack does not plan to migrate languages or break the monolith for the sake of architectural fashion. Changes are driven by measured limits, not by trend.