Outbound Email Service (Threads) — business view
Technical trace: Email Command Engine (CommandController)
1. Business Summary
Bulk email dispatch of cross-entity threaded messages, with brand-aware subject formatting (e.g., a Task email appends the Job name; an RFR email appends region and qualifier).
2. Business Value
Reliable, asynchronous notification delivery — keeps stakeholders informed.
3. Users / Stakeholders
System.
4. Workflows
- Periodic job queries unsent threads.
- Dispatches via SMTP using a configured profile.
- Marks sent.
5. Sub-Features
- Per-entity subject formatting.
- Security-aware viewer lookup.
6. Business Rules
- Unsent + permitted-viewer rule.
7. Data Entities
Entity Thread.
8. Entry Points
- Web services thread send action.
9. Inputs & Outputs
- Inputs: pending threads.
- Outputs: emails, sent flags.
10. Integrations
- SMTP.
11. Calculations / Logic
- N/A.
12. Status Lifecycle
- Pending → sent.
13. Permissions
- Service-level.
14. Reports & KPIs
- Emails sent per period.
15. Risks & Observations
- High volume could throttle SMTP.
16. Source Code Evidence
app/Controller/WebServicesController.php.
4. Cross-Feature Observations
- Status drives almost everything. Statuses on Jobs, Tasks, Invoices, ResourceSelections, RFRs, Internal/Vendor Invoices propagate automatically: change → queue → security rebuild → optional email/SQS → optional SAP sync. Misclassified statuses cause many downstream effects.
- Security engine is pervasive. Almost every entity has pre-computed security tables and depends on a uniform check pattern; misconfiguration hides records or grants over-broad access.
- A small number of mega-modules carry most of the business logic — these are concentrated reservoirs of business rules that must be maintained carefully.
- Auto-cascade of entity creation (Job + PO + Project + Contact + Files + AutoPlan + TMS) means a single intake action can mutate up to seven different parts of the system. Failure handling is mostly manual.
- Reference-data sprawl — roughly 200 master data tables. Validating new business rules often requires touching multiple tables.
- Two parallel CRM data layers (native CRM and FreshSales mirror) — both consumed by different features. Inconsistencies between them may show up as conflicting reports.
- Brand isolation runs through almost every entity — everything that breaks brand isolation is a major incident.
- Background jobs do almost everything important (security, satisfaction, content checker, SAP sync, FreshSales import, scheduled reports). They lack a unified retry/back-off strategy and a single operations dashboard.
- Localization-domain modeling is rich — phase types, language groups/regions, MT engines, DTP/QC levels, weighted words, TM brackets — concepts unique to LSPs and not generic.
- Hard-coded special cases — discrete ID blacklists in security cron, manager IDs in Cognito, brand defaults, SAP date cutoffs, currency placeholders. Each is an operational shortcut that has not been retired.
5. System-Wide Risks
Architecture
- A small number of very large modules concentrate most of the business logic — change risk is high and testability is low.
- Multiple
.origand.orig.origbackup files coexist with active modules — operational unclarity about which version is canonical. - Heavy reliance on configuration (security, templates, custom fields, master data) without clear change control.
- Pre-computed security can become stale or oversized — manual blacklists are needed today.
- The email-driven command engine creates a parsing surface that is hard to evolve safely.
Scalability
- Long synchronous waits in the TMS / Memsource flow.
- Destructive full-replace FreshSales sync risks data loss and large mass writes.
- Cron backlog can grow during outages without back-pressure controls.
- The mobile API does its own data composition and may not scale horizontally cleanly.
Security & Compliance
- Hard-coded API tokens, JWTs, and fallback admin credentials in integration controllers.
- Password copies stored in browser cookies during login — replayable if cookie is captured.
- Password reset tokens never expire — long-lived bypass risk.
- Raw concatenated request data in some queries — possible injection vectors.
- Audit attribution fields used during substitution are not validated.
- No multi-factor authentication observed.
- No rate limiting on inbound webhooks/integrations.
- Some background endpoints have framework-level auth bypassed and must be network-restricted.
Data Integrity
- Cyclic risk in account/company hierarchies (parent/root references).
- Default placeholder currency code can be sent to SAP if account data is incomplete.
- Hard-coded date cutoff for SAP eligibility excludes historical data.
- Soft-delete is rare — cascading deletes can orphan transactional data.
Integration
- Partner APIs use hard-coded auth and have no retry/back-off.
- Inbound SAP REST endpoints lack idempotency keys.
- TMS file-cache vs. filesystem can drift.
- Memsource has a hard-coded fallback credential path.
6. Open Questions (For Business Stakeholders)
- Auto-plan defaults. Where are the canonical "risk factor" and per-task productivity defaults maintained? Per account, per brand, per language pair, or globally?
- Selection ranking. What is the official tie-breaking rule across price, rating, availability, and evaluation score?
- Utilization gating. What is the maximum-utilization threshold beyond which a resource is excluded from selection?
- Evaluation decay. Should old ratings weigh less than recent ones? Currently they appear equal-weighted.
- PO sharing rules. Under what conditions does an account allow PO use across related accounts?
- Brand-template inventory. For each brand, which client/vendor invoice PDF templates are required? What is the fallback if missing?
- SAP date cutoff. Why is "post-2018" hard-coded? Should it be configurable per integration?
- FreshSales sync. Is full-replace acceptable, or should incremental sync replace it?
- Email command grammar. Is the inbound command grammar documented? How is the sender authenticated?
- Login-as policy. Who can substitute for whom? What audit retention is required?
- Cookie-stored ownCloud password. Can this be replaced by OAuth/OIDC?
- Heavy price-book blacklist. What are these specific records and how should they be remediated?
- Compliance / verification lifecycle. Full lifecycle and SLA?
- Mobile API token lifecycle. Issuance, rotation, revocation rules?
- Auto-creation atomicity. Should Job + PO + Project + Contact creation be atomic? What recovery is expected today?
- Customer pattern derivation. How is the "current pattern" computed?
- Internal invoice approval matrix. Who approves and what triggers escalation?
- Partner mapping templates (Welocalize/Junction/Moravia). Who owns them, how are they reviewed for drift?
- Satisfaction email cadence. Frequency rules, opt-out behavior, language?
- Memsource credential fallback. What is the policy when a user-specific token cannot be obtained?
7. Feature Dependency Map (Text-Based)
User Access & Identity
└── Drives auth context for ALL features
Role-Based Security (Security Engine)
├── Depends on: Master Data (Entity, Roles, Relations, Actor Fields)
├── Triggered by: every entity create/update/delete
└── Drives: per-record visibility/action permissions for ALL features
Master Data
├── Validation/dropdowns for every operational module
└── Calendars affect Resource Availability + Task Scheduling
CRM
├── Lead → Account (conversion)
├── Account → Opportunity → Project → Job → Task chain
├── Account → Price Book → Invoicing math
├── Account → Customer Pattern + Forecasts
├── Activities/Follow-ups/Cases linked across many entities
└── FreshSales sync → Lead/Account/Opportunity/Activity mirror tables
Project Delivery
├── Project → Job → Phase → Task
├── Job ↔ Memsource analysis (weighted words)
├── Task → rejections, vendor availability, working days, evaluations
└── Job → Client Invoice (via PO); Task → Vendor Invoice / Internal Invoice
Auto-Planning
├── Depends on Job + Phase types + Risk + Productivity
└── Triggers Resource Selection
Resources / Vendors / Candidates
├── Cognito → Resource/Candidate provisioning
├── Moodle → Training / certificates
├── Resource Calendars + Availability Requests → Resource Selection
├── Resource Evaluations → Selection ranking
└── Resource Banks/E-cash + Deductions → Vendor Payment
Resource Selection & RFR
├── ResourceSelection ← RFR / Plan / Strategy
├── ResourceSelection → ResourceSelectionsResource → Task assignee
└── Cron-driven scheduling
TMS / Files
├── Memsource → Job analysis + deliverables
├── ownCloud → file cache
├── Welocalize/Junction/Moravia → external offers → internal Tasks/Jobs/RFRs
├── Google Drive → file ingest → Task close
└── Cloud unzip / file relations
Finance
├── PO → Client Invoice eligibility
├── Client Invoice ← Job/Task + finance calculations
├── Client Invoice ↔ Client Payment ↔ Client Payment Detail
├── Vendor Invoice ← verified Tasks
├── Vendor Invoice ↔ Vendor Payment ↔ Deductions/Prepayments/Overtime
├── Internal Invoice (IC) — requires approval before SAP sync
├── TM Analysis Templates + Price Book + Discount Items → invoice math
└── SAP Sync (cron + retry) — accounts, resources, all invoices, payments
Customer Satisfaction
├── Trigger on completed jobs
├── Sends survey → satisfaction → contact/account rating
└── Feedback may escalate to a Case
Content Checker
└── Alerts dispatched via security viewers
Activities / Cases / Notes / Tickets / Files
└── Linked to any operational entity; secured via security engine
Dashboards / Scheduled Reports
└── Aggregate from all operational + finance + resources tables
Mobile API / Web Services / Email Command
└── Reuse all operational features via separate entry points
Background:
Schedulers + Common Crons + AWS SQS + Security Cron
↳ Continuously reconcile, dispatch, notify, rebuild security
End of analysis.