sample 05/in production
SK Agency
A corporate site and a platform where each client follows their own contract, from onboarding to renewal.
- Next
- Prisma
- GSAP
- Three
- Turbo
01
Context
SK Agency works in technology and marketing. The project combines the agency site with a platform where each client follows campaigns, reports, proposals, meetings and tickets, while the team runs everything from an admin panel.
In August, the site followed a change in positioning: from an audiovisual and ads agency to a technology and marketing software house.
02
Starting point
The project started with the site, built around a 3D visual narrative, and grew into the agency's operations.
1
corporate site with a 3D narrative
0
tools for clients to follow the work
0
payments or contracts in the system
03
Timeline
178 commits in the project history. These are the milestones.
May 14, 2026
Site with a 3D narrative
A scroll-driven particle engine, an editorial system and the first case pages.
May 16, 2026
Contracts and integrations
A 95-day contract cycle with pause and renewal, and an OAuth connection to Google Ads.
May 17, 2026
The client portal
Proposals with two-way conversation, meeting scheduling, tickets, dashboards with real campaign data and fully private file storage.
May 19, 2026
Roles and protection
Four roles with distinct permissions and rate limiting on public and authentication routes.
May 27, 2026
Guided onboarding
A step-by-step journey for new clients, from commercial proposal to contract start.
Jun 01, 2026
Home performance
In performance testing, the home page's largest element took 21 seconds to appear. WebP images, a dedicated mobile video and on-demand loading tackled it.
Jun 03, 2026
Payments with Stripe
Checkout during onboarding, a webhook, upgrades with prorated billing and safety guards for live mode.
Aug 15, 2026
New positioning
Home page rewritten for a technology and marketing software house, presenting Atlas as a product.
04
Decision map
Reconstructed from the commit history, the README and the project documentation.
01
The server owns the catalog
Prices, bundles and quotas are defined on the server and adjustable from the admin. The browser never says how much something costs.
02
The contract has a lifecycle
Each contract lasts 95 days, can be paused and renewed, and starts when onboarding ends. Clients see the deadline on their own screen.
03
Permissions in one place
One file says what each role can do, and every admin route checks those rules before acting.
04
Private by default
RLS on public tables and private file storage, accessed through expiring URLs.
05
Real data, not mocks
Dashboards show Google Ads campaigns synced automatically, with 90 days of history for the filters.
06
Heavy only where it fits
The hero's 3D and video run only on desktop. On mobile the page loads light, without giving up its identity.
05
Architecture
The same five layers as this page, applied to the project.
000 m/interface
- Site with a 3D narrative
- Client portal
- Admin panel
030 m/route
- Auth.js with role re-read every session
- Rate limiting
- CSRF-protected OAuth
060 m/service
- Centralized role permissions
- Stripe: checkout, webhook and proration
- Google Ads sync
- Email with Resend
090 m/repository
- Prisma with Postgres
- Server-side commercial catalog
120 m/persistence
- RLS on public tables
- Private files via expiring URLs
06
Code
An excerpt from the private repository, just to show the layer at work.
What each role can do
The middleware only asks whether the person is on the team. Each admin action checks its specific permission before running.
export type Role = "CEO" | "ADMIN" | "AGENT" | "CLIENT";
export const ADMIN_TIER: Role[] = ["CEO", "ADMIN", "AGENT"];
/** True iff the role is admin/agent/CEO — i.e. has access to /dashboard/admin. */
export function isAdminTier(role: Role | string | undefined | null): boolean {
return !!role && (ADMIN_TIER as string[]).includes(role);
}
/** CEO only. */
export function canManageTeam(role: Role | string | undefined | null): boolean {
return role === "CEO";
}07
Outcome
4
roles with distinct permissions
95
days per contract cycle, with renewal
3
integrations: Stripe, Google Ads and Resend
Current status
In production at skagency.com.br.