App
Accepted architecture · 1 October 2026, option 2
Agentfy hosts the harness; Store Deputy API exposes the single MCP; the OpenCart module exposes a protected REST/JSON API. Store Deputy governs connections, actor/shopper context, permissions, approvals and audit without building another harness. Connect → login/register → secure pairing → automatic agent provisioning in Agentfy with Store Deputy MCP → return to the module. App contains teams, agents, account, billing and per-agent chat.
This replaces the earlier same-day direct-module-MCP design. Existing code and prototypes below do not implement the new integration. Shopper sessions and the real OpenCart cart have separate scoped bindings; cookies stay in the shop. See the accepted central MCP decision for boundaries, delivery stages and remaining contract work.
Built; runs on a developer's machine · 1 October 2026. English only. It does one job end to end — connecting a store — and that has only been done with the two local test shops.
The app is where a shop owner signs in and says "yes, connect this shop to my team". It has no chat, no catalog and no price screens yet.
A note on names: other files in the repository call this part "the site". In this section, app means the signed-in application in the app/ folder, and website means the public pages, a separate part.
What a person can do today
- Create an account or sign in.
- Connect a shop. The owner arrives from the Connect button in their OpenCart module, picks the team if they are an owner or admin of more than one, and confirms. They are sent back to the module page they came from.
- See what went wrong. If the link is incomplete, was already used, has expired, or the shop cannot be reached, the owner sees an explanation. A link back to the shop is shown only when the return address belongs to the same shop.
- See their teams and connected stores on the home page.
How the code is arranged
app/slices/
setup/
theme/ Tailwind with the design tokens, and the basic UI components
pinia/ state management
api/ the API client, generated from the API's description
error/ turns an API failure into a message a person can read
i18n/ translations; English only for now
user/
auth/ sign-in and registration, the session, the signed-in check
store/
connect/ the confirmation page for connecting a shop
common/ the page header, the layout and the home pageEach slice is a Nuxt layer: a folder with its own configuration, pages, components, state and translations. A folder becomes part of the app as soon as it has a configuration file; there is no central list to update. Setup slices load first.
Inside a feature slice:
- Pages are thin. A page names its route and renders one component.
- A
Providercomponent does the fetching. Each component group has one. It reads what it needs, calls the API, and decides which display component to show. - Display components only display. They receive data and report what the person did.
- State lives in a store. The session is a Pinia store, not a set of loose helper functions.
The connect page shows the pattern. The page renders one provider. The provider reads the link the owner arrived with, asks the API to connect, and shows either the confirmation or the failure component.
How the app talks to the API
- The client is generated, not written. The API describes its routes; the app's client is built from that description each time the app starts in development.
- The session survives a reload without storing a token. The short-lived access token is kept in memory only. The long-lived one is a cookie that page scripts cannot read, sent only to the sign-in routes. After a reload the app asks the API for a fresh access token.
- An expired access token is renewed once and the request repeated.
- A page that needs sign-in sends a signed-out person to sign in and brings them back afterwards — only to a page of the app itself, never to another site.
- The app runs entirely in the browser. There is no server-side rendering; the API is a separate service.
- The connect link is never passed on. It carries the address of the shop's admin page, so the app tells the browser not to send its own address to other sites.
Rules every slice follows
- All code lives inside
slices/. Nothing sits in root-level component or page folders. - Slice folders are singular.
- State goes in stores, not in composables.
- Component groups are one level deep.
- Colours, type and shapes come from the accepted design system through the theme slice, not from per-page styles.
- Each slice keeps its own translation file next to its pages and components.
The points where the app knowingly differs from CleanSlice are listed in the overview.
Not built yet
- Chat, the Today view, review tables and receipts described in the concept.
- Screens for managing a team. The API can invite people and change roles; the app has no pages for it.
- Ukrainian and Russian. Translation is wired in, but only English exists.
- Password reset and email confirmation.
- A production build and hosting.