NIXIM / MarketingOpen workspace ↗

Marketing Agent workspace guide

Useful content starts with a clear purpose. Marketing Agent is Nixim’s tenant-aware workspace for configuring that purpose, preparing publishing destinations, and tracking the future content workflow.

Release scope: the secure administration foundation. Content generation, scheduled runs, media production and external publishing are not enabled.

Environments

Environment Address Purpose
Production marketing.nixim.co.uk Operational workspace configuration
Development marketing-dev.nixim.co.uk Testing and development
Documentation docs.marketing.nixim.co.uk This guide and architecture reference

The admin displays the current environment in its header. Development and production have different APIs, functions, tables and website buckets. A shared identity pool lets you use the same email and password in both environments; membership and configuration are independent. Saving a development setting does not change production.

Sign-in and recovery

Access is by invitation. Public self-registration is disabled. On your first visit, select Forgot password? First time here?, enter your invited email address, and request a verification code. Enter the code and choose a password with at least eight characters. Then sign in. Codes expire; request a new one if necessary.

The initial Nixim owner is provisioned with a verified recovery email. Passwords are handled directly by Amazon Cognito in Ireland, never by the administration API. The application keeps authentication tokens in memory, so reloading the page requires signing in again. Tokens are not persisted in browser storage. Access tokens last one hour; an active page refreshes them using a one-day refresh token. Sign out revokes the refresh token and clears local session state. An already-issued access token can remain valid until expiration; workspace suspension is checked server-side on each request and immediately blocks tenant operations.

If sign-in succeeds but no workspace is listed, an operator must assign membership. If recovery does not arrive, check spam and ask an operator to check verified email status, Cognito delivery settings and sending limits. Never share recovery codes.

Configure your organisation

Organisation stores your name, line of work, business aims, website URL and time zone. Describe the audience’s practical questions and the expertise you can share. These values are preparation for future generation; no model is called on save.

Owners and administrators can save. Read-only roles cannot update configuration, and the API enforces that restriction. Each save increments a version and creates an audit event in a single DynamoDB transaction. If another person saves first, you receive a conflict. Copy any unsaved changes, choose Reload saved, then apply your changes to the latest version. Switching pages keeps the current in-memory form values; switching workspace, reloading saved settings, or signing out discards unsaved values. Save before switching workspaces.

Publishing stores the preferred interval in whole hours (1–720), content formats, planned social channels and a destination table name. The interval is a preference; no EventBridge schedule is active. Social channel selection does not connect an account. You can create the Nixim social accounts later.

The production Nixim destination is seeded from the existing website’s published content table output. The development destination starts blank to avoid accidentally pointing development publishing at production content. This release grants no cross-project table write permissions. A future connector must verify the table, schema, tenant allowlist and publishing policy before it can operate.

Never enter API keys or passwords into business fields. Provider credentials are not accepted by this release. Future provider connections will store each tenant’s keys separately in AWS Secrets Manager; the browser will never retrieve stored keys.

The content workflow

Stage Intended behaviour Current status
1. Discover Find timely topics aligned with business aims and audience questions Planned
2. Write Research and generate substantive insights with evidence and useful detail Planned
3. Website Publish approved content and make it appear in the latest homepage content Planned
4. Scenarios Adapt the article into Instagram, YouTube, Facebook, TikTok and other scenarios Planned
5. Scripts Produce scripts, captions and calls to action Planned
6. Assets Produce graphics, clips, narration and audio Planned
7. Assembly Render platform-appropriate videos linking back to the article Planned
8. Distribution Publish through connected accounts and retain provider receipts Planned

The initial implementation sequence after this foundation is Nixim website content first, followed by social scenarios, media generation and publishing. Each stage needs explicit run states, retries, idempotency, quotas, usage records and approval policies. A saved preference must never imply that a publication succeeded.

Nixim’s existing website source is at C:/Company/NIXIM/website-v2. It remains a separate application and deployment. The connector must reuse its actual content schema, publication rules and homepage content selection rather than inventing a second incompatible record format. ISS and other clients will have their own allowlisted table destinations even when they share that schema and AWS account.

Costs and usage

The cost page separates three concepts:

AWS cost allocation tags must be activated in Billing. New tag keys and cost data can take time to appear; an empty result is shown as pending, not as a zero-cost claim. Billing data is cached for six hours to limit chargeable Cost Explorer requests. Provider charges are not connected. BYO AI keys will keep provider accounts separate; provider billing visibility depends on supported provider APIs.

All new stacks carry Project=marketing-agent, Environment=dev|prod|shared and CostCenter=marketing-platform. The existing Nixim website remains separately tagged. CloudFront and Route 53 are global; application services reside in Ireland. The Cost Explorer API uses its global billing endpoint. It is read-only and does not move application data to another deployment region.

Architecture

The Angular SPA is served over HTTPS by CloudFront from a private S3 REST origin. Origin Access Control restricts bucket reads to the corresponding distribution. S3 public access is blocked. Extensionless paths serve the SPA entry point. CloudFront applies CSP, HSTS, frame denial, content-type and referrer headers.

Browser sign-in communicates directly with Cognito. The HTTP API validates the JWT issuer and the environment-specific app-client audience. Lambda additionally requires an access token, resolves the subject’s active membership, and checks the selected tenant’s status and role. The request’s tenant header never establishes membership by itself. Dev tokens fail at the production API and vice versa.

Resource group Location Isolation
CodeCommit, deployment artifacts eu-west-1 One project repository and private versioned bucket
Cognito eu-west-1 One shared pool, separate dev/prod clients
HTTP API, Lambda, CloudWatch eu-west-1 Separate per environment
DynamoDB eu-west-1 Four tables per environment, tenant-prefixed keys
Admin and documentation S3 eu-west-1 Separate private website buckets
CloudFront and Route 53 Global Separate distributions and hostnames
CloudFront ACM certificate us-east-1 Required AWS certificate location; no app compute or storage

The infrastructure templates are shared.yaml, certificate.yaml, environment.yaml and website.yaml. They are generated by scripts/generate_infrastructure.py and committed as readable YAML. The shared foundation bootstraps its artifact bucket from a local template; subsequent templates and Lambda bundles are uploaded under content-hashed S3 keys. Change sets are recorded and reviewed for removals or replacements before execution. Each website publication also stores a complete archive and a manifest of object version IDs and content hashes in the private artifact bucket. Dev and prod use identical application files; only their public runtime configuration differs.

Data model

Table Keys and access patterns
ma-{env}-control USER#{sub} / TENANT#{id} lists memberships; TENANT#{id} / META resolves active tenants; TENANT#{id} / SETTINGS reads versioned configuration; PLATFORM#COSTS caches platform billing
ma-{env}-content Reserved for tenant-scoped content and workflow data in the next phase; unused now
ma-{env}-audit TENANT#{id} / EVENT#{UTC timestamp}#{UUID} records configuration changes; query latest 30
ma-{env}-usage TENANT#{id} / MONTH#{YYYY-MM} counts tenant API requests atomically

Tables use on-demand capacity, encryption, point-in-time recovery, deletion protection and retention on stack deletion. The application uses keyed lookups and queries, not scans. Configuration writes use an expected version and transact with their audit event. Counter failure fails the request, rather than silently claiming complete metering. The current usage metric measures accepted workspace requests, including validation failures after membership resolution; it does not estimate database or model charges.

API and permissions

All authenticated routes require a Cognito access token in Authorization: Bearer and, except /v1/me, a verified workspace selection in X-Tenant-Id. JSON errors return a stable code, safe message and request ID where available. API and browser configuration responses are not cached. CORS allows only the matching environment.

Route Permission Result
GET /health Public Synthetic service and environment health
GET /v1/me Authenticated access token Active authorised workspaces
GET /v1/settings Active member Workspace configuration, automation disabled
PUT /v1/settings Owner or admin Validated versioned save plus audit event
GET /v1/costs Owner, admin, billing or analyst Tenant usage; aggregate costs only for platform operators
GET /v1/audit Active member Latest 30 configuration events, without actor identities

The API role has access only to this environment’s tables and logs, plus read-only Cost Explorer access. It has no permissions to existing website tables, Secrets Manager, social APIs or model providers. The current foundation does not expose tenant creation, invitations, role editing, subscriptions or self-service onboarding.

Operations and recovery

CloudWatch retains Lambda and API access logs for 30 days. Access logs record route, status and request ID, not request bodies or authorization tokens. Application unexpected-error logs record only error type and request ID. Lambda error and throttling alarms exist per environment. No email or SMS alarm destination is configured yet; an operator must monitor these alarms until notifications are added.

HTTP API throttling is 15 requests/second with a burst of 30 per environment. Lambda has a reserved concurrency ceiling of 10 per environment. There is no content worker, external publishing permission or scheduled automation in this release.

For a failed configuration save, use the request ID to inspect API and Lambda logs. For a 409 conflict, reload the latest settings. For a 403, check membership, role, tenant status and selected environment. For a 401, sign in again and ensure the token comes from the matching app client. Do not weaken authorization to debug.

To roll back application code, deploy the previous immutable Lambda artifact and restore the previous versioned S3 frontend objects with their matching public configuration. Invalidate CloudFront paths after publishing. Do not replace or delete DynamoDB tables to roll back code. Point-in-time restore creates a new table; inspect and validate it before changing configuration or IAM. A destructive database restore/cutover requires a separate explicit operational decision. This foundation does not claim a completed disaster-recovery exercise or production SLA.

To suspend a tenant, set its META.status to suspended; all tenant API operations will fail on the next request. To revoke one user’s access, suspend or remove the specific environment membership. Shared Cognito disablement affects both environments. Future offboarding must handle retention, exports and deletion as an auditable workflow rather than deleting a tenant’s keys ad hoc.

Onboarding another organisation

Provision an invited Cognito identity and a separate tenant ID. Create the tenant metadata, initial versioned configuration, and membership records in each intended environment. Never copy a Nixim membership into another tenant without changing the tenant identifier. A platform-operator flag is privileged and must remain false for customer memberships. Customers may own their workspace without seeing aggregate platform billing. The operator bootstrap script is only for the initial Nixim owner and never resets an existing user’s password.

Later provisioning must support organisation-specific aims, social connections, content formats, schedules, provider secrets and destination table allowlists. No customer should supply a raw IAM role or arbitrary table ARN that the publisher automatically trusts. Same schema does not mean shared authorisation.

Release boundaries

This release intentionally has no customer-facing website, payment processing, public registration, AI calls, external publishing, video rendering, social OAuth, automatic scheduler, exact tenant AWS cost allocation, or provider key management. The full supplied design remains the longer-term reference; current owner choices and foundation decisions define this release’s deviations.

Documentation is public and contains architecture and operating guidance only. Never publish credentials, recovery codes, customer data or security-sensitive incident details here. Deployment evidence and local test captures are kept out of the public documentation build unless deliberately summarised.

References