REPOCITYAI FOR EVERYONE

RepoCity in eight scenes

A company whose software runs most of the work by itself. Daniel steers and approves.

A business calls or writes. The phone assistant and incoming mail add it as a customer in the CRM.

Daniel audits the website with the RadarAuditor: 108 checks in 14 areas, from load time to assistants built on artificial intelligence.

The open points become the quote. The CRM sends it together with the audit report as one file.

When the customer accepts, in the app, by mail or on the phone, the CRM creates order and subscription. Order confirmation and maintenance contract go out without approval.

Changes to website and Google profile are prepared as drafts. Daniel approves each one, then the server applies it.

Once nothing is open, the CRM closes the order, sends the invoice and asks for a Google review.

Every month the subscription invoice goes out by itself. Daniel starts the due monthly audit with one tap in the Cockpit.

All parts

Cockpit

The message centre above all of the company's apps: every event as a notification on the phone, right onto the lock screen, with one-tap actions.

App behind a sign-in. Test stage without customer operation.

What it does

  • Notifications for every event from CRM and marketing, for monthly audits and for every call.
  • Up to two buttons per notification, on the lock screen too: send reminder, start audit, confirm acceptance.
  • The result replaces the notification under the same tag instead of adding a second one.
  • A button works once and for at most 14 days; the authorisation number only reaches the device with the notification.
  • Every morning an overview, from “all quiet” to the points that are waiting.
  • If mail stays unread for an hour, the Cockpit asks once a day whether the server is running.

From the event to the tap on the lock screen

Five stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  1. Runs by itselfWhere: Database, schema cockpit

    Event

    An app reports something to the message centre. The same report counts once, so recurring checks do not flood the phone.

  2. Runs by itselfWhere: Edge Function cockpit-push

    Push

    The notification goes encrypted to every registered device without holding up the event that caused it.

  3. Daniel taps or approvesWhere: Phone, lock screen too

    Notification with buttons

    Up to two buttons, for example “send” and “do not send” for a reminder.

  4. Runs by itselfWhere: Database, cockpit.run_action

    Action

    Checked first: button offered, not yet used, notification at most 14 days old. Then the action runs in the CRM and a reply sentence replaces the notification.

  5. Runs by itselfWhere: schedule in the database

    Morning overview and watchdog

    An overview every morning; every hour a look at whether mail is being read.

Skills at work here

Interface

  • Preact and TypeScript
  • Vite
  • Installable web app (progressive web app)
  • Own service worker

Push messages

  • Encryption by RFC 8291 (Request for Comments, an internet standard)
  • Sender identification by RFC 8292 (Voluntary Application Server Identification)
  • Edge Function in Deno

Database

  • Triggers on the CRM tables
  • Asynchronous sending with pg_net
  • Schedules with pg_cron
  • Live updates for the open app
  • Row level security

The Cockpit in five scenes

The message centre above all of the company's apps.

Every event from the apps arrives as a notification on the phone, right onto the lock screen.

Up to two buttons per notification. One tap sends a reminder, for example.

The result replaces the notification under the same tag instead of adding a second one.

An overview every morning. If mail stays unread for an hour, the Cockpit asks whether the server is running.

All parts

CRM

The company's CRM (customer relationship management): customers with their complete file, quotes, orders, subscriptions, invoices, reminders, contracts and every outgoing mail.

App behind a sign-in. Test stage without customer operation.

What it does

  • Today: what is due, from approvals and due monthly audits to the calls of the last 24 hours.
  • Customer file with subscriptions, contracts, calls, every outgoing e-mail, the RadarAuditor audits and all documents.
  • “Send quote” sends the quote itself; the page shows whether the mail is waiting, sent or failed.
  • Invoices with one number range, payments, cancellation and electronic invoices in the XRechnung format.
  • Contracts from templates and requests for a Google review with one reminder; every customer can object at any time.
  • Tax adviser package: one ZIP archive per month, quarter or year with every invoice, tables and the DATEV booking batch.

From the quote to the tax adviser package

Seven stations that hand work to each other. Each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  • The customer decides
  1. Daniel taps or approvesWhere: RadarAuditor app or CRM

    Create the quote

    Items from the open points of the audit, products and prices from the CRM.

  2. Daniel taps or approvesWhere: CRM and mail service

    Send the quote

    “Send quote” puts the mail in the outbox. The mail service attaches the quote with the audit report and sends it.

  3. The customer decidesWhere: CRM database

    Acceptance

    Acceptance from the app, by mail or on the phone: an order, and one subscription per monthly item at the quoted price. Order confirmation and maintenance contract go out without approval.

  4. Runs by itselfWhere: CRM database

    Complete the order

    After “optimisation finished” or on Daniel's tap: the invoice of the one-off items is finalised and sent, a review request is created.

  5. Runs by itselfWhere: schedule in the database

    Daily routine

    Every day: invoices of due subscriptions, due monthly audits and review requests, with one reminder after the configured number of days.

  6. Daniel taps or approvesWhere: Cockpit

    Reminder

    The routine prepares it. Because payments are entered by hand, no reminder goes out without Daniel's tap on “Send”.

  7. Daniel taps or approvesWhere: CRM, invoices page

    Tax adviser package

    Every invoice document of the period, invoices, payments and open items as tables, and the DATEV booking batch.

Skills at work here

Interface

  • Preact and TypeScript
  • Vite
  • Installable web app (progressive web app)
  • Tests with Vitest

Database

  • PostgreSQL in Supabase with migrations
  • Row level security
  • Business logic as database functions and triggers
  • Schedules with pg_cron
  • Database tests on a real PostgreSQL

Mail service

  • Edge Function in Deno
  • Fetching over IMAP (Internet Message Access Protocol)
  • Sending over SMTP (Simple Mail Transfer Protocol)
  • Quote, invoice and reminder documents with pdf-lib

Accounting

  • DATEV booking batch in the EXTF 700 format, standard chart of accounts SKR03
  • XRechnung electronic invoice
  • ZIP archive with fflate

The CRM in five scenes

The company's customer management: every customer with their complete file.

The file holds everything: subscriptions, contracts, calls, every e-mail and every audit.

From quote to order, invoice and payment, with one number range for every invoice.

Every day the database runs its routine, not only when the app is opened.

One package for the tax adviser per month, quarter or year, with the DATEV booking batch.

All parts

Incoming mail

The company mailbox is fetched every five minutes. Mail from known customers goes into their file; replies to quotes and mail from unknown senders are read by a language model and assigned to customers and quotes. This reading is built for the company's own server.

Fetching and filing are done by the CRM's mail service. Test stage without customer operation.

What it does

  • Fetches inbox and sent mail every five minutes; every mail of a known customer goes into their file.
  • A mail from a customer with a sent quote and every mail from an unknown sender is queued for reading.
  • Checks whether the sender is provably genuine.
  • The language model reads each mail without any tools; the mail text is treated as data, not as an instruction, and the answer is checked against a fixed format.
  • The CRM records an acceptance by itself only when the sender is genuine, the answer is sure and the quote is unambiguous and still valid.
  • If an unknown sender is a customer, the CRM adds them and files all their stored mails; anything else lands on the review list.
  • If reading fails three times, a notification follows; if mail stays unread for an hour, the Cockpit reports it once a day.

From the mail to the CRM entry

Six stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  1. Runs by itselfWhere: CRM mail service

    Fetch

    Every five minutes the mail service fetches new mail from inbox and sent.

  2. Runs by itselfWhere: CRM mail service

    Sort

    Mail of a known customer: into the file. Reply to a sent quote and unknown sender: queued for reading, with the check whether the sender is genuine.

  3. Runs by itselfWhere: the company's own server, built for it

    Read

    A language model reads each queued mail without tools; the answer is checked against a fixed format.

  4. Runs by itselfWhere: CRM database

    Record

    Sure acceptance from a genuine sender with a valid quote: acceptance in the CRM. Sure decline: recorded and reported. New customer: added, mails in the file.

  5. Daniel taps or approvesWhere: Cockpit

    Ask back

    Everything else goes to the Cockpit, a possible acceptance with “confirm acceptance” and a note whether the quote has expired or the sender is not confirmed.

  6. Runs by itselfWhere: schedule in the database

    Watchdog

    If mail is not read for an hour, the Cockpit reports it once a day.

Skills at work here

Mail service

  • Edge Function in Deno
  • Fetching over IMAP (Internet Message Access Protocol)
  • Original mails in storage, deleted after sorting

Sender authenticity

  • DMARC (Domain-based Message Authentication, Reporting and Conformance)
  • DKIM signature (DomainKeys Identified Mail) of the sender domain

Queue

  • Claiming with “for update skip locked” so no mail is read twice
  • Up to three attempts, then a notice

Reading

  • Language model without tools
  • Mail text fenced as data
  • Answer checked against a fixed format: customer, unsure, not a customer or automated; accept, decline or other

Incoming mail in five scenes

The company mailbox is fetched every five minutes.

Mail from known customers lands in their file. Replies to quotes and unknown senders are queued for reading.

Built for the company's own server: a language model reads each queued mail, and the answer is checked against a fixed format.

An acceptance is recorded automatically only when all three conditions hold.

Everything else goes to the Cockpit, a possible acceptance with the button “confirm acceptance”.

All parts

Phone assistant

Built for the company's own server: answers calls on the business number in German. Speech recognition, language model and voice run on that server with its graphics card; no cloud service is involved.

The business number is entered once the company exists.

What it does

  • Says at the start that an artificial intelligence is speaking and that the call is written down, as Article 50 of Regulation (EU) 2024/1689 requires.
  • Answers only from the business facts and the active products in the CRM; it never invents prices, dates or promises.
  • Recognises callers by their number, compared digit by digit; an unknown caller is added as a customer, even without an e-mail address.
  • Takes down the request and creates the task “callback <name>, <number>”.
  • Accepts or declines quotes, but only when the line belongs to the quote's customer and the quote has been sent and is still valid.
  • Stores every call with transcript and summary; if the same call arrives twice, it is stored once.
  • A free female German voice until Daniel's own voice is cloned.

One call, from the ring to the notification

Seven stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  • The customer decides
  1. Runs by itselfWhere: the company's own server, built for it

    Call

    The provider routes the business number over a SIP trunk (Session Initiation Protocol) to the server; LiveKit takes the call.

  2. Runs by itselfWhere: the company's own server, built for it

    Greeting

    The notice about the artificial intelligence sits in the CRM settings; it can be reworded, but not emptied and not interrupted.

  3. Runs by itselfWhere: the company's own server, built for it

    Conversation

    Speech recognition with faster-whisper, answers with Qwen 3 on Ollama, voice with Piper. After the configured maximum length it says goodbye.

  4. Runs by itselfWhere: CRM database

    Take the request

    Find or add the customer by number or a spoken e-mail address, enquiry and callback task in the CRM.

  5. The customer decidesWhere: CRM database

    Acceptance or decline

    It is decided automatically only when line, customer and quote match. Otherwise the caller always hears the same sentence and learns nothing about other customers' quotes.

  6. Runs by itselfWhere: Server, CRM and Cockpit

    End of call

    The language model on the server writes the summary; transcript, summary and outcome go into the CRM, the notification “call from …” into the Cockpit.

  7. Daniel taps or approvesWhere: CRM and Cockpit

    Callback and confirmation

    Daniel calls back and confirms an unclear acceptance with “confirm acceptance”.

Skills at work here

Telephony

  • LiveKit server and LiveKit SIP
  • LiveKit Agents in Python
  • Valkey as the store LiveKit needs

Speech

  • Speech recognition with faster-whisper, model large-v3-turbo
  • Speech pauses with the Silero model
  • Turn detection
  • Voice with Piper, German female voice ramona
  • Speech service with FastAPI

Language model

  • Qwen 3 with 8 billion parameters on Ollama
  • Tools: look up the caller, take the request, decide on a quote, note a callback, end the call

Operations

  • Docker Compose with the NVIDIA Container Toolkit, graphics card with at least 12 gigabytes of memory
  • Settings with pydantic-settings
  • Retries with tenacity
  • Behaviour tests with a real call session and a scripted model
  • Free licences only: Apache 2.0, MIT, BSD and GPL 3.0

The phone assistant in five scenes

Built for the company's own server: answers calls on the business number in German.

At the start it says that an artificial intelligence is speaking and that the call is written down.

It recognises callers by their number, takes down the request and creates a callback task in the CRM.

Speech recognition, language model and voice are built for the company's own server, without a cloud service.

Every call goes into the CRM with transcript and summary, and into the Cockpit as a notification.

All parts

RadarAuditor

The company's product: measures how visible a local business is on Google, Google Maps, in directories and in assistants built on artificial intelligence, and turns that into a sales report, a quote and a monthly before-and-after report.

App published; collector and evaluation are built for the company's own server. Test stage without customer operation.

What it does

  • Enter only the website address: the server works out business, town, trade and search terms itself.
  • 108 checks in 14 areas, scored against a fixed check catalogue.
  • Evaluation with the talk text “what you tell the customer” and the three biggest levers.
  • Every check expands: why it matters, what was measured, the fix.
  • Quote on site: items from the open points, prices from the CRM.
  • Optimisation of website and Google profile: changes as drafts, each approved by Daniel.
  • Monthly audit with a before-and-after report.

From the website address to the monthly audit

Eight stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  1. Daniel taps or approvesWhere: App on phone, tablet and computer

    Start the audit

    Daniel enters only the website address and picks the checks.

  2. Runs by itselfWhere: the company's own server, built for it

    Collect

    The collector recognises business, town and trade and fetches the data.

  3. Runs by itselfWhere: the company's own server, built for it

    Score

    108 checks in 14 areas, scored against the fixed catalogue.

  4. Runs by itselfWhere: the company's own server, built for it

    Evaluate

    A language model turns the raw data into findings, fixes and report texts; the output is checked against a fixed data format.

  5. Daniel taps or approvesWhere: App and CRM database

    Quote and acceptance

    Create the quote, “send quote”, then the customer's decision: “accepted” creates the order in the CRM.

  6. Daniel taps or approvesWhere: App and server

    Optimisation

    Changes to website and Google profile are prepared as drafts. Daniel sees each one before and after and approves or rejects it.

  7. Runs by itselfWhere: Database

    Optimisation finished

    When no change is left open, the database writes the event and the CRM closes the order.

  8. Daniel taps or approvesWhere: Cockpit and server

    Monthly audit

    When a subscription is due, one tap in the Cockpit runs the audit again; the report shows before and after.

Skills at work here

Collector

  • Python
  • Browser automation with Playwright
  • httpx and BeautifulSoup
  • Docker

Scoring

  • Check catalogue as a YAML file
  • Data models with Pydantic
  • Tests with pytest

Evaluation

  • Language model without a screen, with its own skills for evaluation and optimisation
  • Output checked against a fixed data format

Reports

  • Print-ready reports with WeasyPrint
  • Templates with Jinja2
  • Charts with Matplotlib

App

  • Preact and TypeScript
  • Installable web app (progressive web app)
  • Charts with Chart.js
  • Radar with three.js

Data

  • Supabase and PostgreSQL
  • Row level security
  • Job queue in the database

The RadarAuditor in five scenes

Measures how visible a local business is on Google, in directories and in assistants built on artificial intelligence.

A website address is enough. The server works out business, town and trade itself.

108 checks in 14 areas from one single catalogue.

The evaluation delivers the talk text for the customer and the three biggest levers.

After acceptance the CRM takes over: order, invoice and a new audit every month.

All parts

Website service

Websites for customers are built from a kit of templates. Quote, order and invoice run through the CRM like every product of the company.

In progress.

What it does

  • Websites for customers from a kit of templates.
  • The RadarAuditor measures how visible a business's current website is.
  • The CRM keeps customer, quote, order and invoice.

Where the website service fits

Four stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  • In progress
  1. Daniel taps or approvesWhere: RadarAuditor

    Audit

    The RadarAuditor measures the current website: technology, structure, content, business details and hidden data for Google.

  2. Daniel taps or approvesWhere: CRM

    Quote

    Quote with products and prices from the CRM, sent through the CRM.

  3. In progressWhere: Template kit

    Build

    The website is built from the kit of templates.

  4. Runs by itselfWhere: CRM database

    Order and invoice

    The CRM keeps order and invoice as for every product.

Skills at work here

Template kit

  • Website templates

What the RadarAuditor measures on a website

  • Website technology: 10 checks
  • Page structure: 10 checks
  • Content and service pages: 12 checks
  • Business details on the website: 6 checks
  • Hidden data for Google and AI: 8 checks

The website service in three scenes

Websites for customers are built from a kit of templates.

The RadarAuditor measures a website's technology, structure, content, business details and hidden data for Google.

Quote, order and invoice run through the CRM like every product of the company.

All parts

Marketing

Research with every figure checked against its source. Campaigns and posts go to the planner for approval and are posted by hand from the company accounts.

Planner as an app behind a sign-in; the research tool runs on the operator's computer. Test stage without customer operation.

What it does

  • Every figure of a finding is looked up in the text of its source before a person reads it; this needs no language model and costs nothing.
  • A person keeps or drops every finding; every decision is stored as a file.
  • Campaigns from checked findings: every figure of a post is matched against the findings it cites.
  • Planner for 13 channels in one calendar, from blog and LinkedIn to newsletter.
  • A post with figures that lack a checked source cannot be approved.
  • Reports which points have gone stale; deletes and overwrites nothing.

From research to the post

Seven stations; each one says who triggers it and where it runs.

  • Daniel taps or approves
  • Runs by itself
  1. Runs by itselfWhere: Operator's computer

    Research

    A research session writes each finding as its own file, with statement and source; a statement without a source counts as an error.

  2. Runs by itselfWhere: Operator's computer

    Check the figures

    Every figure is looked up in the text of the source, whether web page, PDF (Portable Document Format) or file in the workspace.

  3. Daniel taps or approvesWhere: Review page

    Review

    A person sees every finding with its check result and keeps or drops it.

  4. Runs by itselfWhere: Operator's computer and database

    Campaign

    Posts from the kept findings; every figure of a post has to appear in a cited finding, then the campaign goes to the planner.

  5. Daniel taps or approvesWhere: Marketing app

    Approval in the planner

    In the calendar every post gets its date; only a post whose figures are backed can be approved.

  6. Daniel taps or approvesWhere: Cockpit and company accounts

    Post

    When the date has come, the Cockpit says “post now”; posting is done by hand from the company accounts.

  7. Runs by itselfWhere: Operator's computer

    Freshness

    Reports points whose source is too old or whose address no longer answers.

Skills at work here

Research tool

  • Python
  • Command line with verify, review, apply, pack, stale and campaign
  • Data models with Pydantic
  • Reading sources with httpx and pypdf
  • Retries with tenacity

Planner

  • Preact and TypeScript
  • Charts with Chart.js
  • Texts with markdown-it
  • Tests with Vitest

Database

  • Schema marketing in Supabase
  • Approval lock as a database trigger
  • Reminders with pg_cron

Marketing in five scenes

Research with every figure checked against its source.

Every figure is looked up in the source text before a person reads the finding.

Only kept findings go into campaigns, and every figure of a post needs a backing.

The planner shows the posts of all 13 channels in one calendar.

When the date has come, the Cockpit reminds. Posting is done by hand from the company accounts.