AI 资讯
I Started Building a Premium Template Marketplace — Week 1 Progress, Stack & What's Coming
I've been thinking about this problem for a while. Developers and businesses need quality websites fast — but the options are either overpriced custom builds, outdated templates, or starting from scratch every single time. So I decided to build the solution myself. Softchic is a premium template and ready-made website marketplace — production-ready, built on modern stacks, designed to actually look good. This is Week 1 of building it in public. Why Softchic The market exists. Developers need templates. Businesses need websites. But most template stores are either bloated, outdated, or built on stacks nobody wants to touch in 2026. Softchic is different — every template ships with: Modern stack (Next.js, TypeScript, Tailwind CSS v4) Clean, production-ready code Premium design out of the box The name went through 25+ candidates across multiple languages before landing here. Clean, available, memorable — Softchic. The Stack Framework: Next.js 14 (App Router) Language: TypeScript Styling: Tailwind CSS v4 Components: shadcn/ui Payments: Lemon Squeezy (international) + Paystack (Nigeria) Email: Resend Deployment: Vercel Design language: dark and premium — #0D0D0D background, #2563EB blue, #F97316 orange accents. Week 1 — What Got Built ✅ Waitlist page — designed and ready to deploy ✅ Navbar — responsive, dark-themed ✅ WaitlistForm — wired to Resend for email capture ✅ Brand system — colors, typography, full design identity locked ✅ Payment architecture — Lemon Squeezy + IP-based currency detection via ipapi.co with PPP pricing for global fairness The waitlist goes live very soon. Follow me here on Dev.to — I'll drop the link the moment it's live. Early subscribers get first access when the store launches. The launch goal: 200 waitlist subscribers before opening the store. That's the benchmark. No exceptions. What's Next Waitlist page goes live 🚀 Product listing page Template preview system First upload — a SaaS landing page template The Real Talk Building a marketplace fr
AI 资讯
Framework-Specific Env Patterns
Your schema is portable. But each runtime loads environment variables differently. CtroEnv adapters bridge the gap — same validation logic, different data sources. Node.js: process.env + .env Files The @ctroenv/node adapter loads .env files and wraps process.env : import { defineEnv , string , number } from " @ctroenv/core " import { loadEnv } from " @ctroenv/node " const env = defineEnv ( schema , { source : loadEnv () }) loadEnv() resolves files in order: .env — shared defaults .env.{NODE_ENV} — environment-specific ( .env.development , .env.production ) .env.local — local overrides (gitignored) Later files override earlier ones. process.env takes precedence unless override: true . Monorepo Root loadEnv ({ path : " ../.. " }) // look up two directories for root .env Native Node 22+ Node 22 has built-in process.loadEnvFile() . Use native: true to delegate: loadEnv ({ native : true }) // uses process.loadEnvFile() if available Falls back to the custom parser on older Node versions. System Fallback By default, only file values are returned. With system: true , missing keys fall through to process.env : loadEnv ({ system : true }) Standalone Parser Use parseEnvFile() directly for custom file loading: import { parseEnvFile } from " @ctroenv/node " const content = readFileSync ( " .env.custom " , " utf-8 " ) const vars = parseEnvFile ( content ) Handles quotes, multiline values (backslash continuation), interpolation ( ${VAR} ), comments, and export prefix. Vite: Build-Time Validation The @ctroenv/vite plugin validates during the build: // vite.config.ts import { ctroenvPlugin } from " @ctroenv/vite " export default defineConfig ({ plugins : [ ctroenvPlugin ({ schema : " ./src/env.ts " }), ], }) If DATABASE_URL is missing, the build fails — no broken artifacts shipped. Schema Options Pass a file path or inline definition: // File path — imports the module, looks for `schema` export ctroenvPlugin ({ schema : " ./src/env.ts " }) // Inline definition ctroenvPlugin ({ schem
AI 资讯
VERCEL_EXPERIMENTAL_DEV_SKIP_LINK: Stop Dev Link Hangs
TL;DR If the Vercel CLI keeps trying to open a dev link against your Vercel project during local next dev runs, set VERCEL_EXPERIMENTAL_DEV_SKIP_LINK=1 in the shell that launches the dev server, or add it to .env.local at the project root, and restart the process. The flag is opt-in, all-uppercase, and only affects local CLI behaviour. It never reaches your deployed build, and the production runtime on Vercel does not read it. If the CLI still tries to link after a restart, scroll to Debugging when the skip link isn't working for the version-compatibility and process-tree checks that catch the cases the basic setup misses. I have shipped this flag in three production monorepos and the same four mistakes account for almost every "I set it and it did nothing" report I see. What VERCEL_EXPERIMENTAL_DEV_SKIP_LINK actually does VERCEL_EXPERIMENTAL_DEV_SKIP_LINK is an opt-in environment variable the Vercel CLI honours when it runs alongside a local Next.js dev server. Its job is narrow: tell the CLI to skip the step where it would normally reach out to Vercel and create or refresh a dev link against your Vercel project. A "dev link", in the Vercel sense, is a local connection record that lets vercel dev and some Vercel-only local emulators (KV, Postgres, Edge Config) pull real values from a Vercel project. It is useful when you want production-shaped data during development, and a real annoyance when you do not — for example in CI sandboxes, offline laptops, monorepo workspaces that share a single project, or any time you want next dev to behave like a plain Node process without the CLI wrapping it. The variable is shipped under the VERCEL_EXPERIMENTAL_ namespace, which Vercel uses to mark features that can change between CLI versions. That has two practical consequences: the name must be uppercase with underscores, and you should not build production logic on top of it. I treat it like a local-dev knob, set per shell session, and never check it into CI as a hard dependen
AI 资讯
I built a free online toolbox with 260+ tools — here's the tech stack and what I learned
Every small task used to mean a new tab. JSON formatter on one site, GST calculator on another, PDF merger somewhere that wanted my email before it would merge two pages. Ads everywhere, slow UIs, and that low-grade worry about uploading a payslip or invoice to a server I do not control. I got tired of juggling twenty bookmarks for work that should take thirty seconds — so I started building one place for all of it. What ToolReign is ToolReign is a free online toolbox: 260+ utilities across 15 categories , all running in your browser. Developer tools (JSON formatter, JWT decoder, API client), text utilities, SEO helpers, PDF and image tools, spreadsheets, and a finance section I built with India in mind — GST with CGST/SGST/IGST splits, EMI and SIP calculators, HRA exemption, gratuity, income tax estimates, and more. The idea is straightforward: open a tool, do the work, leave. No signup wall, no file uploads to a backend, no account to manage. I am Anirudha Sonwane , a Senior Software Engineer at Giant Leap Systems in Pune. ToolReign is a side project I build around my day job — not a pitch deck, just something I wished existed. The tech stack decisions Next.js 14 App Router and static export Each tool lives at its own route under src/app/{category}/{tool-slug}/ . That maps cleanly to SEO: one URL, one search intent, one page of metadata. The site exports statically ( output: 'export' ), so production deployment is uploading an out/ folder to static hosting — no Node server to babysit. The App Router made this scale. Add a page component, register the slug in tool-registry.json , and the sitemap, category hubs, and search index pick it up automatically. At 260+ tools, hand-maintaining URLs would have broken within a month. 100% client-side — the decision that shaped everything This was the core architectural bet, and it is also the privacy story: your data never leaves the browser. Finance calculators are plain TypeScript math with useMemo . PDF merge and split use
AI 资讯
What I Learned Building an SEO-Focused Gaming Website with Next.js
Over the past few months, I've been building a gaming website focused on Elden Ring guides, calculators, and tools. While the project started as a simple hobby, it quickly became an interesting experiment in SEO, content strategy, and web development. Here are some lessons I learned along the way. Building the Site Was Easier Than Getting Traffic Launching a website with Next.js was straightforward. Getting visitors was much harder. Many developers underestimate how competitive search traffic can be, especially in gaming niches where large sites already dominate search results. Publishing a website is only the first step. Why I Chose Next.js The project uses: Next.js TypeScript React Tailwind CSS The biggest advantage was SEO. Server-side rendering and static generation helped ensure that search engines could easily crawl and index pages. Performance was also excellent compared to many traditional CMS solutions. Tools Attract Different Users Than Articles One interesting discovery was that calculators and interactive tools behave differently from standard content pages. For example: Guides answer questions. Tools solve problems. A player may read a guide once, but they might return to a calculator dozens of times while planning different character builds. This makes tools valuable long-term traffic assets. Internal Linking Matters More Than Expected When new content was published, internal links helped search engines discover and understand related pages. For example: Build guides linked to calculators. Calculator pages linked to stat guides. Stat guides linked to weapon builds. This created a stronger topical structure around the Elden Ring ecosystem. Search Traffic Takes Time One of the biggest lessons was patience. Many pages received: Zero impressions Zero clicks No rankings for days or even weeks. Then suddenly search impressions started increasing as Google tested pages across different queries. Traffic growth was rarely linear. Content Clusters Work Well Inst
AI 资讯
Making product recalls executable with Aurora DSQL and Vercel
Live demo: https://safestate.vercel.app , code: https://github.com/usv240/safestate A product recall today is basically a notice. It lives on a webpage, or a PDF, or an email that somebody is supposed to read. Say the problem out loud and it gets uncomfortable fast. A recalled crib can be listed and sold to another family, and nobody in that sale ever sees the recall. Reselling recalled goods is actually illegal, and recalled infant products have killed kids. I spent this hackathon building something to close that gap. I called it SafeState, and the idea is small: make the recall do something. When a second-hand item is listed or sold, the marketplace checks SafeState first, and recalled units get blocked right at checkout. It is precise down to the serial number, so safe units still sell. It runs on the stack this hackathon is about. A Next.js front end on Vercel, with Amazon Aurora DSQL behind it. Why DSQL is the whole point here The promise SafeState has to keep is this: the moment a recall lands in any region, no marketplace anywhere should ever read that product as "safe" again. That is a strong consistency problem, not a nice-to-have. If there is any window where a recalled product still looks safe, that is exactly when it gets sold. An eventually consistent store or a nightly sync leaves that window open. DSQL's active-active, multi-region setup with strong consistency is what closes it. I set up a real peered cluster across us-east-1 and us-east-2, with us-west-2 as the witness. Write a recall through one region's endpoint and you can read it back from the other region right away. There is a page in the app that lets you run that yourself. The one trick that makes it work DSQL runs on snapshot isolation (PostgreSQL REPEATABLE READ) with optimistic concurrency. It catches write-write conflicts at commit time. Snapshot isolation will not protect you from write skew, so I had to design around that. To guarantee that a recall and a sale of the same product actua
AI 资讯
You don't need NextJS: here's why
This is the public, sanitized version of an internal proposal I wrote to move our production app off Next.js. Next.js is the default answer to "I want to build a React app." It's a great framework. But default and necessary aren't the same word. The gap between them quietly cost us speed, debuggability, and a surprising amount of cross-team friction. We were building an authenticated, data-heavy product: dashboards, filters, charts. Almost every screen lived behind a login and updated in response to clicks. For that shape of app, server-side rendering wasn't buying us much, and it was charging us a lot. First, the only question that matters The right architecture depends on what you're building. Content-first: Marketing sites, blogs, storefronts, docs. Mostly public, SEO matters, lots of static content. SSR/SSG is a genuinely great fit. Use Next.js. Seriously. Application-first: Internal tools, dashboards, admin panels, SaaS consoles. Behind auth, highly interactive, bottlenecked by your API and DB — not by React rendering. Put an application-first product on a content-first framework and you pay for machinery you never use. That was us. What SSR actually cost us Production debugging got harder Server-rendered errors don't map cleanly to the components you wrote, so root-causing took longer every single time. Client-side, the error happens in the browser with a stack trace that points at your component. Boring and fast to fix. Server components fought our tests You can't cleanly unit test a server component that renders other server components. Tools like React Testing Library expect renderable elements, not the serialized output a server component produces. We ended up making design choices purely to stay testable. Tail wagging the dog. Authentication became a distributed-systems problem This was a big one. If you gate protected pages on the server, the server must read and validate the token on every request, then propagate auth state through hydration. That singl
AI 资讯
You don't need Vercel Pro. You need your stack to sleep.
TL;DR for vibe coders: Shipped an app with Cursor, Claude Code, or v0 and got a scary Vercel or Neon bill? You probably don't need a bigger plan. You need a few fixes. Not technical? Copy the agent-rules folder from the companion repo into your project and tell your AI editor "apply these cost rules." That's the whole job. You don't need Vercel Pro. You don't need to "Launch" on Neon. A lot of the time you need the opposite of an upgrade. You need your stack to go to sleep. Here's the moment that started this. A Neon bill landed, across three small Next.js apps running on Vercel with a Neon Postgres database, and the breakdown was lopsided in a way that gave the whole game away. $32.65 of it was compute. Storage was 5 cents. History and data transfer were zero. The meter said 308 hours of compute time in about three weeks, which is a database awake for roughly fifteen hours a day, every day. The instinct when a bill climbs is "I must be getting traffic, time for a bigger plan." So before doing that, I opened Google Analytics. Zero users in the last 30 minutes. Meanwhile the database compute was pinned active, and had been more or less around the clock. So this was never a storage problem or a traffic problem. Almost the entire bill was one thing: paying for a database to stay awake doing nothing. Both of those things were true at the same time, and here's the part I'll say up front so nobody has to guess: I didn't hand-write the mistakes that caused this. AI coding agents did. I described features, the agent shipped working code, and that code carried a handful of patterns that quietly defeat scale-to-zero. That's not a confession of bad engineering. It's just what building looks like in 2026. Most of us are vibe-coding onto serverless and cloud infra now, and the agent optimizes for "make the feature work," not "keep the database asleep when no one's around." It has no idea your compute bills by the hour it stays awake, so it has no reason to care. That's the whole
AI 资讯
React Server Components in 2026: Patterns, Pitfalls, and When to Actually Use Them
React Server Components in 2026: Patterns, Pitfalls, and When to Actually Use Them Most React Server Components problems stem from teams treating them like regular components with a new rendering location. The architecture shift is deeper than that. RSC fundamentally changes where code executes, what data can cross boundaries, and how developers reason about state. Teams that ignore these constraints burn weeks debugging serialization errors and performance regressions. The pattern that production teams overlook is the server/client boundary itself. Understanding where computation happens, what props can serialize, and when to break out of server rendering determines whether RSC improves or destroys your application's performance. Core Concepts: How RSC Actually Works Under the Hood React Server Components execute on the server and send rendered output to the client. No JavaScript bundle ships for these components. The client receives a serialized tree describing what to render, along with holes for client components to fill. The execution model works like this: the server runs your component tree, fetches data directly, and serializes the result. When the payload reaches the browser, React reconstructs the UI without hydrating server component code. Only client components hydrate with their JavaScript bundles. RSC execution flow from server to client This distinction is critical. Server components cannot use hooks like useState or useEffect because they don't exist in the browser. They render once on the server per request. Client components ship JavaScript and can use the full React API. The implication here is that your component tree becomes a mix of server and client code. The boundary between them determines your bundle size, waterfall depth, and debugging complexity. Production-Ready Patterns: Streaming, Suspense, and Data Fetching The correct pattern for data fetching in server components eliminates the request waterfall. Fetch data directly in the component
AI 资讯
Why I Chose DeepSeek Over GPT-4 for a Free AI Conversation App
I did not choose DeepSeek because I think GPT-4 is bad. I chose it because I was building a free app, and free apps teach you what actually matters pretty fast. The question was simple: how do I keep sessions cheap enough that people can practice a lot without me lighting money on fire? The answer pushed me toward DeepSeek-V3 (and later R1 for specific tasks). The real constraint was volume The app is a conversation practice tool. People come in to rehearse hard talks, not to admire the model. A single practice session runs 8-15 turns. Each turn is roughly 300-600 tokens in, 100-300 out. Multiply that by five sessions a week per active user and the costs start compounding. Here is what the math looked like when I was choosing (mid-2026 pricing): Model Input cost (per 1M tokens) Output cost (per 1M tokens) Cost per 10-turn session (est.) GPT-4o $2.50 $10.00 ~$0.04-0.06 GPT-4 Turbo $10.00 $30.00 ~$0.12-0.18 DeepSeek-V3 $0.27 $1.10 ~$0.004-0.007 DeepSeek-R1 $0.55 $2.19 ~$0.008-0.012 At scale, the difference between $0.005 and $0.05 per session is the difference between running a free product and needing a paywall after three conversations. I wanted people to come back daily without hitting a wall. What DeepSeek handled well It stayed in character for 10-15 turns. It pushed back when the user got vague. It followed persona heuristics (numbered if/then rules in the system prompt) about as reliably as GPT-4o did for our use case. For salary negotiation rehearsal, the model needs to say "that's not in the budget" and hold that position for three more turns while the user tries different approaches. DeepSeek-V3 did this. Not perfectly, but reliably enough that sessions felt real. It also made the app easier to run as a free product. People can try, fail, reset, and try again without me worrying about per-session cost. Where GPT-4 was still better GPT-4 (and 4o) is smoother with nuanced emotional wording. When a conversation gets subtle, loaded with subtext, or requires pick
AI 资讯
Building an interactive Palworld map with Next.js, Leaflet and Supabase
As a solo developer I wanted a fast, mobile-friendly interactive map for Palworld that didn't bury me in ads. The result is Pindrop , and here are a few of the technical decisions behind it. Rendering 1000+ markers without jank The interactive map uses Leaflet with a custom marker-clustering layer. Markers are served as static JSON from the edge and hydrated client-side, so the first paint is server-rendered and the heavy marker work happens after. A breeding calculator as a pure function Palworld's breeding combos are deterministic, so the breeding calculator is just a lookup over a precomputed table rather than a backend call. That keeps it instant and fully cacheable. Stack Next.js (App Router) for SSR + static generation Leaflet for the map layer Supabase for the small amount of dynamic data Vercel for hosting and edge caching If you play Palworld, the guides section collects the breeding, location and boss notes I kept losing track of. Feedback from other devs welcome — especially on the clustering approach.
AI 资讯
From MERN to Next.js: My Journey as a Full Stack Developer
Hi everyone 👋 I'm a Full Stack Developer with experience in JavaScript, React.js, Next.js, Node.js, Express.js, MongoDB, and WordPress development. Over the last few years, I have worked on multiple projects ranging from company websites to full-stack web applications. In this article, I want to share my experience transitioning from the traditional MERN stack to Next.js and why it has become my preferred framework for modern web development. Why I Started with MERN Stack The MERN stack was my first choice because it allowed me to build complete applications using JavaScript. Technologies MongoDB Express.js React.js Node.js Benefits ✅ Single language across frontend and backend ✅ Huge ecosystem ✅ Fast development ✅ Easy API integration Challenges I Faced As projects became larger, I started facing issues like: SEO limitations Performance optimization Routing complexity Code organization Server-side rendering requirements This is where Next.js entered the picture. Why I Switched to Next.js Next.js provides several powerful features out of the box. Server-Side Rendering (SSR) Pages can be rendered on the server which improves SEO and initial page load performance. 2.** Static Site Generation (SSG)** Perfect for blogs, landing pages, and marketing websites. 3.** App Router** The new App Router makes routing cleaner and more scalable. Server Components Less JavaScript is sent to the browser, improving performance. Better Developer Experience Features like: File-based routing Built-in image optimization Middleware API routes make development faster and cleaner. My Current Tech Stack Frontend Next.js React.js TypeScript Tailwind CSS Backend Node.js Express.js MongoDB Tools Git & GitHub Postman Vercel Contentful CMS What I Learned The biggest lesson I learned is: Focus on solving real business problems instead of chasing every new technology. Frameworks will change, but understanding JavaScript fundamentals, APIs, databases, authentication, and system design will always be
AI 资讯
Don't Let Claude Haiku Do the Math — A Two-Stage Read-Aloud Coach Design, and the Prompt Swamp
📝 Originally published in Japanese on Zenn. This is the English version. Canonical: https://zenn.dev/uya0526_design/articles/satellite2_haiku-coaching 📚 This is satellite article #2 in my "Read-Aloud Speed Meter dev log" series. For the whole picture, see the main article ; for the AmiVoice integration, see satellite #1 . Where This Sits This article covers the part of the read-aloud speed meter that hands the measured numbers to Claude Haiku to generate coaching as "one compliment + one improvement." Many articles that use generative AI just dump it on the model: "here's the recognized text, evaluate it nicely." This article is the opposite. Don't let the LLM do the math. All computation and rule-based decisions are settled in code, and Haiku only does the wording. I'll go through how I designed this "two-stage" split, and which swamps I sank into during implementation. Four things: Why "code does the math, Haiku only does the wording" (the role-split design) The finalized prompt, and the messages / system / cache_control implementation First-hand findings: the prompt cache that didn't work The moment real data slapped me with "written in the prompt ≠ obeyed" 💡 I'm an ex-Java engineer learning TypeScript in public, so I drop in Java comparisons. Why Not Let Haiku Do the "Math"? Up front: Haiku is more than enough for feedback generation — in fact, you can shape the task into something Haiku is good at. The key is the role split. I settle all the metric computation (speaking speed, stagnation rate, threshold decisions) entirely in code. So by the time it reaches Haiku, it's already settled facts like this (below is from running labelMetrics on a real measurement — reading the Heike sample during development; stagnationRate is a number for percentage display): { "pureSpeakingSpeed" : 322 , "pureSpeakingSpeedEvaluation" : "slightly fast" , "stagnationRate" : 0 , "stagnationRateEvaluation" : "few" } Haiku's only job is to translate these numbers and labels into warm, c
AI 资讯
Calling AmiVoice's Synchronous HTTP API Through a Next.js BFF — Auth, multipart Order, and the WebM Trap
📝 Originally published in Japanese on Zenn. This is the English version. Canonical: https://zenn.dev/uya0526_design/articles/satellite1_amivoice-bff 📚 This is satellite article #1 in my "Read-Aloud Speed Meter dev log" series. For the whole picture, see the main article . Where This Sits In the read-aloud speed meter app, this article covers the part that sends browser-recorded audio to the AmiVoice API to get back recognized text plus timestamps. The theme is calling an external API without exposing your API key to the browser — in other words, implementing a BFF (Backend for Frontend). The main article only touched the highlights, so here I go down to a level you can reproduce yourself. Specifically, four things: Why you must not call AmiVoice directly from the browser (why a BFF is needed) AmiVoice's synchronous HTTP auth, parameters, and multipart order Why the browser's MediaRecorder output (WebM/Opus) passes through as-is Reshaping the raw JSON with a pure-function mapper and testing it with fixtures 💡 I'm an ex-Java engineer learning TypeScript in public, so I drop in comparisons to Java here and there. Why a BFF Is Needed Using the AmiVoice API requires an API key. And that key must never appear in browser-side code. Frontend JavaScript is fully inspectable by the user, so writing the key there leaks it instantly. So I insert a relay that holds the key. [Browser] ──audio Blob──▶ [Next.js API Route (BFF / holds key)] ──▶ [AmiVoice API] record / display audio field reshape into u / d / a speech → text The browser only calls my own API Route ( /api/recognize ), and that Route attaches the key server-side and forwards to AmiVoice. The key is just read from process.env and never ends up in the bundle shipped to the browser. ☕ Java comparison: This is the same as a Spring @RestController reading an external API key from application.yml (env vars) and relaying without showing it to the client. Think "a thin Servlet that hides the secret and relays an external API."
AI 资讯
Measuring Japanese Read-Aloud Speed with AmiVoice Timestamps — A Coaching App That Doesn't Stop at STT-to-Claude
📝 Originally published in Japanese on Zenn. This is the English version. Canonical: https://zenn.dev/uya0526_design/articles/main_article_reading-speed-meter Introduction — What I Built I built a web app that lets you read a Japanese passage aloud, measures your speed and fluency, and has an AI coach return a one-line piece of feedback. 🌐 Demo: https://reading-speed-meter.vercel.app/ 📦 Repository: https://github.com/uya0526-design/reading-speed-meter The flow is simple. You read a passage aloud into the mic (up to 10 seconds) while looking at the script — I prepared the opening lines of two Japanese classics, The Tale of the Heike and Hōjōki — and when you press "Measure," : AmiVoice API recognizes the audio, the code computes your pure speaking speed (characters/min) and stagnation rate from that result, and Claude Haiku returns coaching as "one compliment + one improvement." (Measurement starts on a button press after recording — it never runs automatically.) This article aims to be a single, self-contained piece covering the whole picture, the design decisions, and the reproduction steps . 💡 Where this sits in my journey I'm an ex-Java engineer learning TypeScript and Python in public. This was my first project where I deliberately adopted "AI-collaborative development" as a clear mode. Throughout, I'll drop in comparisons to Java — hopefully useful for anyone coming from a similar background. What You'll Get From This Article How to design evaluation logic that fully exploits the per-word timestamps AmiVoice returns How to build a BFF (Backend for Frontend) so API keys never reach the browser A "two-stage" design where code does the math and Claude Haiku only does the wording First-hand findings you only learn by verifying — e.g., "I thought I'd optimized it, but it wasn't actually working" I include concrete endpoints, parameters, and environment variables so you can reproduce it yourself. My Learning Style (AI Transparency) 💡 Learning companions & how this art
AI 资讯
I Got the proxy.ts Matcher Wrong for Three Projects Before I Understood Why
A few days ago I published a post about the three-layer auth model and the invoice incident that made...
AI 资讯
How I Built the Two Missing Payload CMS v3 Plugins — Reviews, JSON-LD & Real Production Bugs
Running 23 European e-commerce shops on Payload CMS v3 taught me that some things simply don't exist yet. So I built them. Background I maintain a multi-clone e-commerce infrastructure — 23 Next.js + Payload CMS v3 shops deployed across Europe, each on its own subdomain and language. Think fr.myshop.com , de.myshop.com , sk.myshop.com ... all running on the same codebase with country-specific patches. While building this, I kept running into two missing pieces that no one had published for Payload v3: A customer reviews system with admin moderation and Google star ratings Complete Schema.org JSON-LD for Google rich snippets (Product, BreadcrumbList, ItemList, AggregateRating) Both are now published on npm. Here's what I built, the bugs I hit, and how I solved them. Part 1 — The Reviews Plugin What didn't exist Search npm for payload reviews or payload ratings — you'll find nothing for v3. The official plugin ecosystem covers SEO, forms, redirects, Stripe... but not customer reviews. Building the collection The reviews collection itself is straightforward — relationship to products , rating (1-5), status select (pending/approved/rejected), author fields. The tricky parts came later. Access control gotcha: Payload v3 uses a roles array, not a role string. This breaks if you copy v2 patterns: // ❌ Wrong — always returns false update : ({ req }) => req . user ?. role === ' admin ' , // ✅ Correct for v3 update : ({ req }) => req . user ?. roles ?. includes ( ' admin ' ), Prevent self-verification: Users can POST any field on create: () => true collections. Lock verified in a beforeChange hook: hooks : { beforeChange : [ ({ data }) => { if ( ! data . status ) data . status = ' pending ' data . verified = false // admin-only, always reset on create return data }, ], }, Email protection: read: () => true on the collection exposes authorEmail in the public API. Add field-level access: { name : ' authorEmail ' , type : ' email ' , access : { read : ({ req }) => req . user ?.
AI 资讯
Your Next.js API Route Is Leaking Diagnostics in Its 400 Responses
A data export endpoint dumps system diagnostics when it hits an invalid field. Feed it garbage, read the debug output, grab the flag. A data export feature lets you pick which profile fields to download. The UI only offers valid fields through checkboxes, so everything looks locked down. But the API behind it accepts arbitrary field names -- send it one it doesn't recognize, and instead of a clean error, it dumps full system diagnostics including internal feature flags. That's where the flag is. You'll bypass the frontend, hit the endpoint directly, and read what comes back. Lab setup Start the lab: npx create-oss-store@latest Or with Docker (no Node.js required): docker run -p 3000:3000 leogra/oss-oopssec-store The app runs at http://localhost:3000 . What you're targeting The app has a profile page at /profile with a Data Export tab. It lets users download their own data in JSON or CSV by selecting fields through checkboxes ( User ID , Email , Role , Address ID ) and clicking "Export Data". The UI looks safe -- you can only pick from a fixed set of valid fields, so there's no way to submit an invalid one through the browser. But that's just client-side validation. The endpoint behind it is POST /api/user/export , and it accepts a JSON body with two parameters: { "format" : "json" , "fields" : [ "id" , "email" , "role" ] } The fields value is an array of strings. The API checks each field against an allowlist. Valid fields? You get your data back. Invalid fields? The API throws an error -- and that error says way too much. Step-by-step exploitation 1. Log in You need an authenticated session. Use one of the seeded accounts: Email: alice@example.com Password: iloveduck Log in through the UI at /login , or grab a session cookie via curl: curl -c cookies.txt -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"alice@example.com","password":"iloveduck"}' 2. Explore the Data Export tab Go to /profile and click the Data Export
开发者
I Built a 4-Sided Plot Area Calculator with 2D & 3D Visualization
I Built a 4-Sided Plot Area Calculator with 2D & 3D Visualization Most online plot calculators only work for simple rectangular plots. However, many real-world properties have four sides with different measurements, making area estimation much more difficult. That's why I built a 4-Sided Plot Area Calculator that allows users to enter the North, South, East, and West dimensions and instantly calculate the approximate plot area. 🔗 https://www.premiumconverters.com/plot-area-calculator Features 📐 Supports irregular 4-sided plots 🏠 Calculates area in Marla, Kanal, Acres, and more 🖼️ Interactive 2D top-down visualization 🏗️ Isometric 3D plot rendering 📏 Feet & inches input support 📱 Mobile-friendly experience Why I Built It In many countries, especially in South Asia, property dimensions are often recorded as side measurements rather than perfect geometric shapes. Existing tools rarely address this use case properly. I wanted to create a simple solution that homeowners, buyers, real estate professionals, and developers could use without needing complex surveying software. The Result The calculator transforms four side lengths into a practical estimate while providing visual feedback that helps users better understand their property's shape. Building tools that solve real-world problems is one of the most rewarding parts of software engineering. Have you ever built a niche tool that unexpectedly helped thousands of users?
AI 资讯
Le SDK Stripe nous a menti en 9 millisecondes : 4 tests pour confondre un bug d'environnement avant de le patcher
La trahison du chiffre Vendredi 15 mai, 16 h 13. L'alerte Sentry remonte sur le téléphone. La première réinscrite Phase 1 attend devant l'écran de paiement, son nom est en haut de mon onglet. Je pose la canette, je rouvre l'écran. La tasse à tête de Françoise, sur le poste d'à côté, capte un reflet jaune que je remarque sans le regarder. La stack trace tient en plein écran. Le stack trace s'ouvre, neuf champs sur dix à null , et un chiffre que je n'ai pas vu venir. type = "StripeConnectionError" message = "An error occurred with our connection to Stripe." code = null statusCode = null requestId = null duration = 9 ms Neuf millisecondes. Sur une route Vercel en région Paris, un DNS résout en quarante millisecondes, un handshake TLS coûte cent à deux cents. Neuf millisecondes, ce n'est pas un appel réseau qui a échoué. C'est un appel réseau qui n'a jamais eu lieu. Le SDK n'est pas arrivé jusqu'à la fibre. L'instinct propose immédiatement trois patchs. Timeout serverless Vercel — j'ajoute maxDuration , je redéploie. Clé révoquée — je vais la rouler. Compte Stripe restreint après le passage en mode live — j'ouvre un ticket support. Ces trois hypothèses sont plausibles. Aucune des trois n'est falsifiable par le symptôme seul, et c'est précisément ce qui les rend dangereuses : chacune ouvre un cycle de quinze à trente minutes avec rollback à la fin si elle se trompe. Multiplié par trois, on tient une demi-journée perdue avec la cliente toujours en train de cliquer. Je n'ai pas le temps. Une réinscrite attend. Quatre tests, dans l'ordre Je connais la classe d'incident — « preview marche, prod casse » , ou son symétrique. La règle, pour cette classe, c'est qu'on ne corrige rien tant qu'on n'a pas discriminé les couches. Quatre tests, exécutés dans l'ordre. Chacun élimine une famille d'hypothèses, pas une hypothèse isolée. Et chacun est conçu pour réfuter ce qu'il vient interroger — parce qu'un test qui cherche à confirmer trouve toujours, par sélection, ce qu'il cherche. Te