Available for my first full-time · Valencia, ES

Mario Sanchis
Colomer.

Full-Stack Developer · Salesforce

I build real things while I learn.

Personal projects in production.

Web and full-stack. This is where I build: different stacks, real decisions, and things that get used every day.

Final project · 9/10 TallerApp sign-in screen with the workshop login form

TallerApp

End-to-end management for a multi-brand auto repair shop: clients and vehicles, repair orders, invoicing with PDF and email delivery, inventory with traceable stock and a KPI dashboard. Its core is the scheduler: a sequential queue per mechanic that respects the shop's real working hours and chains availabilities to compute each job's start and end. State machines for orders and invoices, audited critical flow and 259 unit tests. Final degree project (TFG).

  • Angular 21
  • PrimeNG 21
  • NestJS 11
  • TypeORM
  • PostgreSQL 16
  • JWT + Passport
In production POLYBOT sign-in screen with the Face ID entry button

POLYBOT · Algorithmic trading

Autonomous bot trading weather markets on Polymarket with real money: it pulls the Open-Meteo GFS ensemble (31 members), builds the empirical probability distribution, contrasts it against the order book and places on-chain orders. 33 markets registered, 8 active. LLM decision agents, three layers of risk gates, on-chain fill reconciliation and a PWA dashboard with push notifications.

  • Python 3.12
  • FastAPI
  • Angular 21 PWA
  • Polymarket CLOB V2
  • web3.py · Polygon
  • Open-Meteo GFS
  • Ollama
Live Gym Tracker sign-in screen with the Face ID entry button

Gym Tracker gym.masanco-hub.com

Installable PWA for workout tracking: routines with supersets, weekly schedule, active session with autosave and a rest timer that survives the phone locking via Web Push. History, progress charts and a Coach that suggests cyclic double progression. Own login with passkeys (Face ID). In production since April 2026.

  • Angular 21 zoneless
  • Signals
  • PWA + Web Push
  • WebAuthn
  • FastAPI
  • Ollama

Finance Manager

Personal finance manager replacing two Excel spreadsheets: bank transactions with a verification queue, rule-based categorization, bucket-based investments, net worth, savings goal and debts. The transactions vertical already works end-to-end against the backend; the full 15-table schema is designed and applied.

  • Java 21
  • Spring Boot 3.5
  • PostgreSQL 16
  • Flyway
  • React 19
  • TypeScript
  • Docker
In production jasbct.com hero — JASB Energy & Telco · connecting the cities of the future

JASB Website jasbct.com

Corporate website for JASB Energy & Telco with custom i18n, Schema.org and SEO optimization. Accessible, multi-language and free of heavy dependencies.

  • HTML5
  • Bootstrap 5.3
  • Vanilla JS
  • Custom i18n
  • Schema.org

TallerApp

Auto repair shop management system · Final degree project · Grade 9/10

  • Angular 21
  • NestJS 11
  • PostgreSQL

TallerApp is my final degree project: a complete management application for a multi-brand auto repair shop, built to carry the real workload of a small-to-medium workshop, not a showcase demo.

The differentiating core is the scheduler: when a mechanic is assigned to a repair order, the system automatically computes that mechanic’s next available slot within working hours (8-14 and 15-19, Monday to Friday) and chains the job right behind their current queue, with no overlaps possible, by design.

The critical business rules are centralised in a cross-cutting layer: independent state machines for the repair order and for the invoice, each with its own guards (an unfinished order cannot be invoiced, a paid invoice can only be voided by issuing a corrective invoice under Spanish RD 1619/2012, and so on). Every important flow — login, logout, creations, modifications, voidings — is audited, with access restricted by role.

The notification layer combines synchronous events (when something actionable happens right then: a new order, low stock, an issued invoice) with three scheduled tasks that review what is not instantaneous — overdue invoices, unassigned orders, unconfirmed appointments.

The project is covered by 259 unit tests across 18 suites plus 5 smoke e2e tests, with 12 seed scripts sized on real industry statistics. It was deployed in production (Ubuntu VPS, nginx, systemd) during the defence, with the dissertation written in LaTeX. Final grade: 9.

  1. TallerApp sign-in screen with the workshop login form

    01

    Login and authentication

    A single sign-in screen for the shop’s three roles (Administrator, Shop Manager, Mechanic) — the role travels already resolved inside the login response and signs the JWT.

    The central technical decision: the SPA never touches the token. The backend sets the JWT as an httpOnly + sameSite=strict cookie, secure in production, so no client-side script can read it — the natural protection against XSS. The interceptor only turns on withCredentials so the browser attaches the cookie automatically, and the authentication strategy also accepts a Bearer header as an alternative path for tools such as Swagger or curl during development.

    Authorisation is revalidated in two layers: the route guard in Angular filters what each role sees as a user-experience layer, and the backend revalidates the role on every request by reading the JWT, additionally reloading the user from the database to check they are still active.

    Every successful login and every logout is audited with the IP address. Failed attempts are not recorded individually — rate limiting (5 attempts per minute per IP) already contains brute force, so the audit trail focuses on the system’s legitimate activity.

  2. TallerApp dashboard with the month’s indicators and the weekly appointment calendar

    02

    Operational dashboard and appointment calendar

    The panel’s four indicators (monthly revenue, vehicles in the shop, stock alerts, today’s appointments) are computed with direct aggregate queries against PostgreSQL on every load, with no intermediate cache layers.

    The stock alert threshold is configurable per part, and triggers both the dashboard counter and the corresponding notification.

    The weekly calendar shows customer appointments, colour-coded by status and with direct access to each one’s detail. The scheduler’s output — each job’s estimated completion date, computed by the assignment engine — is consulted in the detail of each repair order, where the heaviest logic of the project lives.

    Notifications combine events generated on the spot (a new order, low stock, an issued invoice) with three scheduled tasks covering what is not instantaneous: overdue invoices, orders unassigned for more than three days, and unconfirmed appointments. It is a system separate from the audit trail: one alerts a human about something actionable, the other leaves a forensic record of who did what.

  3. Detail of a TallerApp invoice with its line items and amounts (fictional data)

    03

    Invoicing and PDF generation (fictional data)

    The invoice PDF is generated on the client itself and downloaded straight to the user’s machine. The email notice is a separate document: an HTML built on the backend with the invoice’s key data (number, amount, dates, IBAN), designed to notify without depending on attachments.

    The invoice state machine follows the Issued → Paid → Voided cycle, with a rule grounded in regulation: a paid invoice can be voided by issuing a corrective invoice, never by deleting it, in accordance with Spanish RD 1619/2012 on payment reversal.

    The due date is treated as a fact derived from the current date, not as a value that depends on a scheduled process updating it: every morning, the system reviews issued invoices whose due date has already passed and generates the corresponding notice.

    Every invoice line supports a percentage discount, correctly computed and applied to the final amount — the basis for special rates or one-off negotiations per customer.

  4. TallerApp inventory list with the stock traffic light and the total value summary

    04

    Inventory and stock traceability

    The parts list uses a traffic light based on proximity to the configured minimum: below the threshold it flags a low-stock alert, feeding both the dashboard counter and the notification system, with a second visual level that anticipates which parts are approaching that point.

    Every stock movement — consumption when a part is used in an order, reversal when a line is deleted, replenishment through the restocking flow — is recorded in a history with type and reason, which makes it possible to reconstruct at any moment how each reference reached its current level.

    The panel summarises at a glance the total stock value, the number of references and the parts below minimum, computed over the loaded catalogue.

  5. TallerApp repair orders with the mechanic assignment dropdown open

    05

    Mechanic assignment and scheduling engine

    This dropdown is the centrepiece of the scheduler. When assigning (or reassigning) a mechanic to an order, the system computes that professional’s next available slot within working hours and chains the new job right behind their current queue, with no overlaps possible by construction. The result — start date, end date and estimated date — is audited and generates a notification to the mechanic with their start time.

    The order state machine follows the Created → Assigned → In Progress → Finished → Invoiced flow, with two backward transitions deliberately allowed: from Finished to In Progress, to reopen a job if a defect is found after closing, and from In Progress to Assigned, to correct an assignment. Invoiced is the only terminal state. Four business guards protect the flow: an unfinished order cannot be invoiced, an order admits a single invoice, and lines of an already closed order cannot be modified.

    Choosing "Invoiced" in the dropdown triggers the creation of the corresponding invoice, and it is the invoice that drags the order into that state — the state is always the consequence of a real business fact, never a direct, isolated change.

    The counters (Pending, In Shop, Finished) and the filters by status, mechanic and customer are resolved over the data already loaded on the client, with chained signals — instant filtering, with no round trip to the server.

  6. TallerApp in dark theme showing the system audit panel

    06

    Dark theme and system audit trail

    Dark mode combines PrimeNG with a set of custom CSS variables under a single switching point: a class on the root element that both systems consume at once, avoiding duplicated theme logic between the component library and the custom styles. The dashboard calendar, depending on an external library with its own visual system, observes that class change to stay in sync with the rest of the interface.

    The audit panel is read-only: there is no write path to that table anywhere in the application, and access is restricted to Administrator and Shop Manager through role guards enforced on the backend. Each record ties together date, user, action and affected entity, leaving a clear trace of who did what and when — login, logout, creations, modifications and voidings are all covered.

Full stack

Angular 21 with PrimeNG, FullCalendar, Chart.js and jsPDF · NestJS 11 with TypeORM, PostgreSQL, JWT + Passport + bcrypt · Docker Compose · Vitest and Jest

POLYBOT

Multi-agent algorithmic trading system · In production since July 2026

  • Python
  • FastAPI
  • Angular 21

POLYBOT is a multi-agent algorithmic trading system that has been trading real money since July 2026, on weather prediction markets. The system pulls the 31-member ensemble of the GFS model through Open-Meteo, uses it to build its own probability distribution for every possible outcome band of the day, and decides whether to take a position by comparing that against the price the market is offering at that moment.

The project manages 33 registered markets, with several running in active production simultaneously, each with its own independent process that can be started or paused without affecting the rest. A risk manager can automatically pause a market when it detects a losing streak, with a scheduled resume.

All access goes through passkey authentication (Face ID), on a session deliberately isolated from the rest of my personal ecosystem: neither the cookie nor the biometric credential is shared with my other projects, even though they live on the same domain.

The notification system was redesigned from scratch after finding a design flaw in its first version (built on Telegram): a state alert must fire when the state changes, never on a timer. The redesign deduplicates by content instead of by date, and replaced a messaging bot with a good share of its commands broken by native push notifications on the PWA itself.

Built with Python and FastAPI on the backend, Angular 21 as a PWA on the frontend, and Ollama for generating natural-language summaries over data the system has already computed deterministically.

  1. POLYBOT sign-in screen on desktop, with Face ID entry and the username form
    The same POLYBOT sign-in screen on the PWA installed on the phone

    01

    Sign-in and session isolation

    Access uses the same pattern as the rest of my ecosystem: passkey (WebAuthn/Face ID) as the main route, with username and password as the alternative. The deliberate difference here is isolation: the session cookie is host-only and never travels to any other subdomain, and each passkey is bound to POLYBOT’s exact domain, so a credential registered here does not work on any other project, or the other way round.

    There is no user table and no roles — it is a single-operator system — but it protects the read-only panel and every action endpoint alike: starting or stopping a bot, pausing a market, changing any parameter.

  2. POLYBOT dashboard with the global indicators blurred by privacy mode, the evolution curve and the market grid

    02

    Operational dashboard

    A financial and operational view of the whole fleet: accumulated performance, hit rate, number of operations and on-chain balance, with a cumulative evolution curve filterable by period. Each active market shows its own card with live status — running, automatically paused by the risk manager, or disabled — so the real state of the entire system reads at a glance.

    It includes a privacy mode that blurs any sensitive figure while keeping the shape of the curve and the rest of the layout intact, meant for screen sharing or documenting the project without exposing financial data. It is the mode every capture in this section was taken in.

  3. POLYBOT cross-market ranking: one row per market with the performance metrics blurred by privacy mode

    03

    Cross-market ranking

    A comparison of every active market, sorted by different performance metrics, computed entirely on the server — the client only formats and displays what already arrives sorted.

    The comparison period is selectable, and every change of time window recomputes against the real data instead of serving a precomputed view. The table order always answers a specific question ("which market is doing better by this metric"), it is not a free exploratory table.

  4. POLYBOT health panel with the status of calibration, resolvers, forecast capturer, agents and services

    04

    System health

    A monitoring panel for the critical processes that keep the system running: when each scheduled task last completed successfully, not simply when it was last attempted — an important distinction, because a process that fails repeatedly is still "running" even though it never succeeds. Each type of task has its own normality threshold according to its nature.

    Anomaly detection and alert delivery happen entirely independently of this screen, in a separate process: that way, if the visible part of the system were to fail, the alerts would still arrive.

  5. POLYBOT notification tray with the daily summary, stopped bots and reconciliation findings

    05

    Notification system

    A centralised notification tray, the result of a full redesign of the alerting system. The previous version sent the same notice several times because of a time-based design flaw; the current version identifies each alert by its actual content, not by when it was generated, avoiding duplicates.

    Only genuinely actionable events arrive as a push notification on the phone — everything else stays available in the tray to be consulted when needed, without interrupting.

  6. POLYBOT system settings with the service controls, notifications, security and appearance modes

    06

    System settings

    A general configuration panel: push notification management, registration of the biometric access credential, appearance and sign-out — with two additions specific to a system that trades real money.

    The first is a manual control over the system processes (API, scheduled agents, the set of per-market bots), designed as a deliberate emergency switch after retiring the external messaging channel that used to partly fill that role.

    The second is privacy mode itself, which blurs any sensitive figure across the whole interface so the system can be screen-shared or documented without exposing financial data — the very function used to prepare the material for this portfolio.

  7. 07

    Operations record

    Every operation is recorded with full identification of the market, the exact moment, the direction taken, price, size, status and final outcome, together with complete traceability of how the order was executed.

    The system also keeps a set of internal model metrics from the exact moment the decision was taken, which are not shown publicly because they would reveal the internal entry criteria.

  8. 08

    Analytics: model diagnostics

    An analysis layer distinct from both the ranking (which compares markets against each other) and the dashboard (which summarises financial state): here the prediction model itself is audited to check whether it behaves as expected.

    It includes eleven aggregated visualisations over the full history — from a calibration curve comparing the model’s estimated confidence against the actually observed hit rate, to performance cross-cut by different dimensions of the forecast and of the operation. It is the screen that answers "is the model behaving consistently?", not "am I making money?".

  9. 09

    System logs

    A custom and deliberately simple logging system, with no external tooling in between: it gathers the log of each market plus the agent scheduler and the API, normalises the format of every source into a single chronological view, with filters by origin and free-text search.

    It prioritises operational simplicity over the sophistication of a full observability stack, in keeping with the real scale of the project.

  10. 10

    Timeline: human-readable traceability

    A chronological feed focused on business events rather than technical logs: operations opened and closed with their outcome, risk manager regime changes with their rationale, market pauses and resumes, alerts from the monitoring system and manual actions by the operator.

    What makes this layer distinctive is that it unifies several heterogeneous data sources —the operations history, the agent snapshots, a write-only audit record, the alert state and the calibration model— into a single coherent timeline, deduplicating events so the same operation is never shown more than once. It covers both what the system did autonomously and what the operator did by hand.

  11. 11

    Per-market and global configuration

    A layered configuration system: a set of global values acting as default behaviour, and the ability to override them independently for each active market, applied hot with no need to restart the system. Each market can also be paused or resumed individually from its own view.

    Which specific parameters are configurable is not detailed publicly, as it forms part of the internal strategy criteria.

Full stack

Python 3.12 + FastAPI · Angular 21 PWA with signals · WebAuthn/passkeys · Web Push + VAPID · Ollama · systemd · nginx · Cloudflare · Ubuntu VPS on DigitalOcean

Gym Tracker

Personal training PWA · In production since April 2026

  • Angular 21
  • FastAPI
  • WebAuthn

Gym Tracker is my personal training log, a PWA I have used daily since April 2026. It comes from a concrete need: keeping track of my routines with full control over how progress and progressions are computed, without depending on a generic app.

The heart of the project is a deterministic progression engine: cyclic double progression around a per-routine rep target, which automatically decides when to add reps and when to add weight, working over each exercise’s full history. A local language model (Ollama) only writes the natural-language summary — the progression decision never depends on the LLM.

Day-to-day access is completely passwordless: passkeys (WebAuthn) verified on the server itself, with Face ID as the gesture that unlocks the device. Rest between sets is announced with real push notifications, which arrive even with the phone locked and the app closed. And the progress charts are hand-drawn in SVG, with no charting library in between.

Built with Angular 21 zoneless and signals on the frontend, FastAPI on the backend, and persistence in JSON and CSV with atomic writes.

  1. Gym Tracker sign-in screen on desktop, with Face ID access and the username form
    The same Gym Tracker sign-in screen in the PWA installed on the phone

    01

    Login and passkeys

    Day-to-day access uses no password: it is a standard passkey (WebAuthn), with Face ID as the gesture that unlocks the credential on the device itself. Verification happens directly on the server, with no intermediate service — the backend validates the cryptographic assertion with the standard WebAuthn library in Python.

    Registering a new passkey is done from Profile, each device with its own credential, which makes it possible to enrol the phone and the laptop separately. The username and password form always coexists as an alternative path, in case the device does not support biometrics or that route is simply preferred.

  2. Gym Tracker Today screen with the day’s routine and the sets in progress

    02

    Today and autosave

    The day’s routine resolves itself: the system consults the weekly planner (the same one edited in Routines) and shows the session due right away, with no need to look for it.

    While training, progress is saved locally on the device continuously — every weight and rep entered, every completed set. Closing the application mid-session loses nothing: on reopening, the session is restored in full, including the rest timer, which recomputes the remaining time against the real clock instead of relying on a counter that would have been left running in the background. A new personal record is computed when the session closes, comparing the maxima achieved against the whole history. The application works offline: if the upload to the server fails, the session is queued and syncs as soon as the network is back.

  3. Gym Tracker session history grouped by month, with tonnage and records

    03

    History

    Every session is recorded with its total tonnage moved — the sum of weight times reps of every completed set — and the personal records achieved that day, grouped visually by month. Cardio sessions (such as walking) share the same data model as strength ones, distinguished simply by their exercise type, which keeps the whole history in a single coherent place.

  4. Gym Tracker routine catalogue with the weekly planner by day

    04

    Routines and weekly planner

    The routine catalogue supports real supersets: two linked exercises where rest does not start until both complete the corresponding set, exactly the way a superset is actually trained at the gym. Each routine is assigned to one or more days of the week from a simple planner, and that mapping is exactly what the Today screen consults to know what is due each day.

    The warm-up lives as its own checklist, independent from the strength routines, reachable at any moment from a shortcut.

  5. Gym Tracker exercise catalogue grouped by muscle group

    05

    Exercise catalogue

    The catalogue starts from a base set and grows with custom exercises at any time, each defined by its name, its muscle group and its type (weight and reps, or time). As soon as an exercise accumulates any record in the history, it automatically becomes available on the Progress screen, with no additional configuration step.

  6. Gym Tracker Coach screen with per-exercise progression recommendations

    06

    Coach: automatic progression

    A single button triggers a complete analysis of the training history. The logic that decides what to progress is entirely deterministic: cyclic double progression around a per-exercise rep target — if the top has not been reached, it suggests adding reps; if the top holds for several sessions, it suggests adding weight and starting the cycle again from the base. Time exercises follow their own progression towards the duration target.

    A language model run locally (Ollama) writes the natural-language summary that accompanies the recommendations — its only function is the wording; the progression decision is already made before the model intervenes, which keeps the system reliable even if the language model is unavailable at that moment.

  7. Gym Tracker progress chart drawn in SVG, with record, current and starting values

    07

    Progress: hand-drawn charts

    The evolution charts are built in pure SVG, with no visualisation library in between — a deliberate decision against far heavier alternatives for what actually needs showing: a progress line, a record and the current point. Each chart automatically scales the value range, keeps the line thickness constant regardless of screen size, and responds to touch or cursor with a dot marking the exact value on any given week.

    The time axis is built by calendar weeks, showing the recent evolution of each selected exercise, with the unit of measure (kilos, seconds or minutes) choosing itself according to the exercise type.

  8. Gym Tracker profile with global statistics, rest alert and Face ID management

    08

    Profile: statistics and rest alert

    The global summary gathers total sessions, accumulated tonnage and records achieved. The rest alert uses real operating-system push notifications — not an alert inside the tab itself — so it arrives even with the phone locked or the application closed, with a custom sound cue designed to be audible on a phone speaker even in silent mode, plus vibration.

    Registered passkeys are also managed from here, along with dark mode, which persists across sessions with no need to set it up again every time.

Full stack

Angular 21 zoneless with signals and standalone · TypeScript · Service Worker/PWA · Web Push + Web Audio API · WebAuthn/passkeys · Python 3.12 + FastAPI · Pydantic · filelock · atomic CSV/JSON persistence · Ollama

I also work with Salesforce.

Seven months of real Salesforce consulting experience during my internship at Capgemini DCX. I keep my Trailhead profile active and it's a path I haven't ruled out.

Trailhead · public profile

Continuous, verifiable learning, day by day.

Badges
77
Points
66,200
Trails
21
Rank
Expeditioner
Expeditioner Rank View Trailhead profile

Areas covered

  • Salesforce Administration
  • Apex
  • Lightning Web Components
  • Flow Builder
  • SOQL
  • CRM Analytics
  • Service Cloud
  • Data Security

Salesforce Junior ConsultantCapgemini DCX

Oct 2025 — Apr 2026 · Intern

Implementation team for European client · Service Cloud + Apex stack.

  • Modeled custom objects and relationships to support new service flows, including validation rules and permission sets.
  • Declarative automations with Flow Builder (Record-Triggered and Screen Flows) replacing recurring manual processes.
  • Configured Lightning Pages and designed email templates for end-user-facing service flows.
  • European data loading with Data Loader and Data Import Wizard, handling duplicates, mappings and post-load validation.
  • Wrote user stories and designed pre-development tests, collaborating with QA and architecture.

Next step Salesforce Administrator certification.

Download Salesforce CV

The tools I work with.

Frontend

  • Angular 21
  • React 19
  • TypeScript
  • JavaScript
  • HTML5 / CSS3

Backend

  • NestJS
  • Spring Boot
  • FastAPI
  • Node.js
  • Python
  • Java
  • PostgreSQL
  • REST APIs

Tools & DevOps

  • Git
  • Docker
  • GitHub Actions
  • Linux / VPS
  • nginx
  • Postman

Salesforce

  • Apex
  • Lightning Web Components
  • SOQL
  • Flow Builder
  • Service Cloud

Who's behind the CV.

I'm Mario, a Computer Engineer from the University of Valencia (2026), and I've been building real software since before finishing my degree: TallerApp (my final degree project, graded 9 — Angular + NestJS + PostgreSQL), Gym Tracker (PWA in production) and, right now, a personal finance manager with React and Spring Boot.

I work in an iterative and methodical way: I read before I write, prototype small, and only then scale. I use AI as a tool, not as a shortcut.

Until April 2026 I was Salesforce Junior Consultant at Capgemini DCX (Apex, Flow Builder, Lightning Pages), seven months of internship where I learned to work in real consulting with agile methodology. I remain open to that path if the right opportunity comes along.

I'm looking for my first full-time job as a Full-Stack Developer (or Salesforce Developer/Consultant), in Valencia or remote.

Download full CV

Looking for someone who builds with judgment? Let's talk.

Better a direct email than a form. I reply within 24 hours and come ready with CV, examples, and availability.