WebServices & Public Endpoints
1. Business Summary
WebServicesController dispatches EntityThread emails (cross-entity threaded messages) in batches; configurable subject suffixes per entity.
2. Business Value
Reliable, asynchronous notification delivery.
3. Users / Stakeholders
System.
4. Workflows
SendThreads()queries unsent EntityThread records.- Uses CakeEmail with profile
transparent. - Subject customization (Task → Job name; RFR → RM region + Qualifier).
- Marks sent after dispatch.
5. Sub-Features
- Per-entity subject formatting.
- Security-aware viewer lookup.
6. Business Rules
- Unsent + permitted-viewer rule.
7. Data Entities
EntityThread.
8. Entry Points
web_services/sendThreads.
9. Inputs & Outputs
- Inputs: pending threads.
- Outputs: emails, sent flags.
10. Integrations
- SMTP (configured via
transparentemail profile).
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.app/Model/EntityThread.php,Message.php.
4. Cross-Feature Observations
- Security engine pervades all modules: Almost every entity has a
Security{Entity}andSecurity{Entity}Usertable, hooks via the SecuritySystem behavior. Most controllers rely oncheckGrant($model, $action, $id)— a uniform pattern but heavily configuration-driven. - Status-driven cascades: Status changes on Jobs, Tasks, Invoices, ResourceSelections, RFRs, Internal/Vendor Invoices propagate automatically: insert into cron_job_sqs → SecuritySystem rebuild → optional email/SQS dispatch → optional SAP sync.
- EngineFunctions component as financial brain: Core calculations (
getJobTaxAmount,getJobGrossProfit,getJobTotalPrice,getTotalPriceMainCurrency,setInvoiceAmount,setVerificationStage) appear across Common, ExportInvoices, and elsewhere — single point of rate/tax logic with many parameters. - Auto-cascade of entity creation:
AutomationComponentorchestrates Job + PO + Project + Contact + Files + AutoPlan + TMS sync from a single call (web/email/mobile entry). - Reference-data sprawl: ~200 admin master tables. Many controllers are pure scaffold — relying on AdminAppController for default behavior.
- Two parallel CRM data layers: native CRM entities (Account, Lead, Opportunity) and FreshSales mirror tables (FreshSales*). Both are referenced from multiple modules.
- Monolithic mega-controllers: CommonController, MobileAPIsController, TmsController, SapController each exceed 5K LOC and own most of the orchestration logic. Refactor candidates.
- Multiple-personas login: Users may switch brands within a session via the multi-user array; the same login can drive multiple security contexts.
- Brand isolation:
brand_idpropagates across most entities; many modules clone reference data per brand (BrandJobTax, BrandsTemplates, BrandsAccountants, BrandsResources, BrandsAssignments). - Email + SQS + Cron triad: Many critical operations (security rebuild, satisfaction surveys, content checker, SAP sync, FreshSales sync, scheduled reports) coordinate through cron + queue + email patterns rather than synchronous flows.
- Localization-domain specifics: Phase types, language groups/regions, MT engines, DTP/QC levels, transcreation, voice-over, weighted words, and TM analysis brackets — concepts unique to LSPs that permeate the data model.
- Hardcoded special cases: Discrete ID blacklists (PriceBook IDs in security cron), brand/form constants (Cognito), hardcoded SAP date cutoffs, currency defaults, and manager IDs hint at operational shortcuts that haven't been retired.
- Background jobs have inconsistent retry semantics: SAP cron has retry table; security cron uses status flags; FreshSales does TRUNCATE-and-replace; Welocalize/Junction/Moravia are fire-and-forget. Operationally these need a unified pattern.
5. System-Wide Risks
Architectural
- Mega-controllers (CommonController, MobileAPIsController, TmsController, SapController) — change risk, no separation of concerns, no testability.
- Multiple
.origand.orig.origfiles coexist with active controllers — unclear which version is canonical (e.g.,CommonController.php,CommonController.php.orig,CommonController.php.orig.orig,CommonController.phpy). - Heavy scaffolding in admin CRUD with no explicit validation — relies on framework conventions.
- Pre-computed security tables can become stale or huge (e.g., PriceBook with thousands of related items) requiring manual blacklists.
- Email DSL for command processing introduces a parsing surface that is hard to evolve safely.
Scalability
- Sleep(120) blocking calls in TMS/Memsource flow.
- TRUNCATE-and-reload FreshSales sync risks data loss and large mass writes.
- Cron backlog may grow during outages (SAP cron retries, security rebuild) without back-pressure controls.
- Massive mobile API does its own SQL building and may not scale horizontally cleanly.
Security
- Hard-coded API tokens, JWTs, fallback admin credentials in integration controllers (FreshSales, Junction, Welocalize, Memsource).
- MD5 password copies in cookies from login flow — replayable if cookie is captured.
- Reset tokens never expire — long-lived bypass risk.
- Raw SQL with
$_POST/$_GETin MobileAPIsController and parts of CommonController/CommandController — SQL injection risk. - Audit on-behalf-id without validation — potential impersonation vector in security cron.
- No MFA, no central session expiry rules visible.
- No rate limiting on inbound webhooks/integrations.
- Open
Auth::allow('*')in security cron controller — must be network-restricted.
Data
- Cyclic risk in account/company hierarchies (parent_id, root_id).
- Currency
"##"defaults in SAP account sync. - Date cutoff '2018-01-01' hard-coded in SAP sync — pre-2018 invoices/payments excluded.
- Soft delete absent in many tables — cascading delete orphans transactional data.
Integration
- External vendor APIs with hard-coded auth and no retry/back-off.
- No idempotency keys for inbound REST endpoints (addClientPayment, addVendorPayment).
- TMS file-cache drift between filesystem and ownCloud cache.
- Memsource fallback to admin credentials if user token absent.
6. Open Questions (For Business Stakeholders)
- Auto-plan productivity & risk factor — how are
getRiskFactor()and per-taskproductivitydefaults configured? Are they per account, brand, language pair, or global? Where is the canonical source? - Selection sort algorithm —
ResourceStrategySort.sort_orderis treated as a sort key, but the deterministic ranking logic is not visible. What is the official tie-breaking and weighting policy across price, rating, availability, evaluation score? - Threshold for utilization gating — what is the canonical max utilization% before a resource is excluded?
- Evaluation decay — should old evaluations weigh less? Currently they weigh equally to new ones.
- PO sharing rules — under what conditions does an Account.account_po_option_id allow shared PO use across related accounts?
- Brand-template inventory — for each brand, which client/vendor invoice PDF templates are required? What is the default fallback if missing?
- SAP cutoff date — why is '2018-01-01' hard-coded? Should it be configurable per integration?
- FreshSales sync semantics — is the destructive TRUNCATE acceptable, or should incremental sync replace it?
- Email DSL grammar — is the command grammar (
CreatePo("AC_ID","PO#",...),CreateRFR()) documented? How is sender authenticated? - Login-as policy — who can substitute for whom? Any audit retention requirement?
- Cookie-stored ownCloud password — is this still necessary? Can OAuth/OIDC replace it?
- PriceBook blacklist — the hard-coded list of IDs flagged "too many related items" — what are these and how should they be remediated?
- Compliance status / verification status — full lifecycle and SLA?
- Mobile API token lifecycle — issuance, rotation, revocation rules?
- Auto-creation cascade — should Job + PO + Project + Contact creation be atomic? What happens if file copy fails after job created?
- Customer-pattern derivation — how is
current_pattern_idcomputed and updated? - Internal invoice approval matrix — who approves and what triggers escalation?
- Welocalize/Junction/Moravia mapping templates — 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 if 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 (SecurityEngine)
├── Depends on Master Data (Entity, Roles, RelationTypes, EntityActorFields)
├── Triggered by every entity create/update/delete
└── Drives row-level visibility & action permissions for ALL features
Master Data Administration
├── Drives validation/dropdowns in every operational module
└── Calendars affect Resource Availability + Task Scheduling
CRM
├── Lead → Account (conversion)
├── Account → Opportunity → Project → Job → Task chain
├── Account → PriceBook → Vendor/Client Invoice pricing
├── Account → Customer Pattern + Forecasts
├── Activities/FollowUps/Cases linked across many entities
└── FreshSales sync → Lead/Account/Opportunity/Activity mirror tables
Project Delivery
├── Project → Job → Phase → Task
├── Job → JobWeightedWord ← Memsource analysis
├── Task → TaskRejection / TaskLog / TaskWorkingDay / TaskVendorAvailability
├── Task evaluation → ResourcesEvaluation aggregate
├── Task → VendorInvoice / InternalInvoice (finance)
└── Job → ClientInvoice (via PO)
Auto-Planning
├── Depends on Job + Phase types + Risk factor + Productivity
└── Triggers Resource Selection
Resources / Vendors / Candidates
├── Cognito Forms → Resource/Candidate provisioning
├── Moodle → Training records / certificates
├── Resource Calendars + Availability Requests → Resource Selection
├── ResourcesEvaluation → Selection sort
└── ResourcesBank/Ecash + 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 → ClientInvoice eligibility
├── ClientInvoice ← Job/Task + EngineFunctions calculations
├── ClientInvoice ↔ ClientPayment ↔ ClientPaymentDetail
├── VendorInvoice ← verified Tasks
├── VendorInvoice ↔ VendorPayment ↔ deductions/prepayments/overtime
├── InternalInvoice (IC) — requires approval before SAP sync
├── TM Analysis Templates + PriceBook + DiscountItems → invoice math
└── SAP Sync (cron + retry) — accounts, resources, all invoices, payments
Customer Satisfaction
├── Trigger on completed jobs
├── Sends survey → ContactSatisfaction → Account/Contact rating
└── Feedback may escalate to EntityCase
Content Checker
└── Alerts dispatched via security viewers
Activities / Cases / Notes / Tickets / Files
└── Linked to any operational entity; secured via security engine
Dashboards / Schedule 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.