AI 资讯
(Alert!)5 Things Even AI Can't Do, GraphQL
GraphQL: A Complete Guide for Developers in 2026 NEWS: MY GAME JUST LAUNCHED Flip Duel Card Battle - Apps on Google Play Outsmart rivals in 1v1 card duels. Joker, bluff, ranked PvP. 5 rounds. play.google.com If you have built more than a couple of APIs, you have probably felt the friction of REST at scale. You ship an endpoint, the frontend team asks for one more field, you version the route, the mobile team needs a different shape of the same data, and six months later you are maintaining /v3/users/:id/full next to /v2/users/:id/summary and nobody remembers which one the Android app actually calls. GraphQL was built to kill that exact pain. It is a query language and runtime that lets clients ask for precisely the data they need — no more, no less — from a single endpoint, against a strongly typed schema that doubles as living documentation. This guide walks through GraphQL from first principles to production concerns. It is aimed at working developers, so expect schema definitions, resolvers, real queries, the N+1 problem, federation, security, and the parts of the ecosystem that actually matter in 2026. By the end you should be able to decide whether GraphQL belongs in your stack and how to build it without shooting yourself in the foot. What GraphQL Actually Is GraphQL is a specification, not a library or a framework. It was created at Facebook in 2012 to power their mobile apps, open-sourced in 2015, and is now governed by the GraphQL Foundation under the Linux Foundation. The spec defines a query language, a type system, and an execution model — but it deliberately says nothing about which database you use, which programming language you implement it in, or how you transport requests over the wire. That last point trips people up, so let it sink in: GraphQL is transport-agnostic and storage-agnostic. Most implementations run over HTTP with JSON, but that is a convention, not a requirement. Your resolvers can pull data from PostgreSQL, a REST microservice, a gR
AI 资讯
Consultar infracciones de tránsito en Argentina con una sola API (JSON, 33 jurisdicciones)
En una gestoría del automotor, consultar las multas de un auto era entrar a 33 sistemas distintos (Provincia, CABA, municipios), cada uno con su captcha y sus caídas. Lo automatizamos con una sola API, la de Multita , y comparto cómo quedó porque sirve a cualquiera que arme herramientas para el rubro automotor o fintech en Argentina. El problema Las infracciones de tránsito en Argentina no viven en un solo lugar. Hay sistemas provinciales (Buenos Aires, Santa Fe, Entre Ríos, Misiones, Chaco, Salta, Mendoza) y municipales (decenas). Ninguno habla con el otro. Consultar a mano son 15 a 20 minutos por vehículo. La solución: una request, todas las jurisdicciones La API de Multita recibe una patente, un DNI o un CUIT y devuelve, en JSON, las actas de cada jurisdicción con su monto y su estado. curl -X POST https://multita.com.ar/api \ -H "X-Api-Key: TU_KEY" \ -H "Content-Type: application/json" \ -d '{"tipo":"patente","valor":"AB123CD","jurisdicciones":"todas"}' { "resultados" : [ { "jurisdiccion" : "pba" , "nombre" : "Provincia de Buenos Aires" , "cantidad_actas" : 2 , "total_oficial" : 418500 }, { "jurisdiccion" : "caba" , "nombre" : "CABA" , "cantidad_actas" : 1 , "total_oficial" : 95000 } ], "resumen" : { "cantidad_actas" : 3 , "total_oficial" : 513500 } } Lo que nos ahorró Pasamos de 15-20 minutos por auto a segundos, y de cuatro ventanas abiertas a una sola llamada. Para una gestoría que cotiza decenas de carteras por día, es la diferencia entre atender 10 clientes o 30. Datos clave Cubre 33 jurisdicciones argentinas (provinciales y municipales), por patente (dominio), DNI o CUIT. Respuesta en JSON al instante; opcional, el total ya cotizado con tu pricing. Hay también una consulta web gratis para probar sin integrar nada. Si tenés una gestoría o estudio y querés esto andando sin programar, escribinos a BA Gestoría y te lo dejamos listo (y un descuento si venís de este post). Docs de la API: https://multita.com.ar/api
AI 资讯
I had real backend auth. The browser just walked around it.
Here's the thing nobody warns you about when you put Supabase behind a "real" backend. My stack is React + FastAPI + Supabase Postgres. Every write goes through FastAPI. Every endpoint checks the user, the role, the ownership. I audited that backend HARD — rate limits, JWT validation, RLS, the whole thing. I was proud of it. And none of it mattered for the two holes I actually shipped. Because the Supabase anon key lives in the browser. It HAS to — that's how supabase-js talks to your project. Which means every logged-in user is holding a key that talks to Postgres directly . Not through my FastAPI. Around it. That anon key is a SECOND API. And I'd spent months hardening the first one while the second one sat there, wide open, the whole time. Hole #1 — the answers were just... readable Quiz questions live in quiz_options , one is_correct boolean per option. My backend never sends is_correct to a student before they submit. Obviously. But the browser doesn't have to ask my backend. // any logged-in student, straight from the console: const { data } = await supabase . from ( ' quiz_options ' ) . select ( ' question_id, label, is_correct ' ) // <- the answer key. all of it. The RLS policy said "authenticated users can read quiz_options ." Totally true for the rows. It just also handed back the column that decides the grade. The answer key. To anyone with a login and ten seconds of curiosity. Fix: column-level REVOKE SELECT from the client role, and let the backend be the only thing that ever reads is_correct . (PR #775.) Hole #2 — they could WRITE things they shouldn't Same class of bug, bigger blast radius. The default Postgres grants let the client role insert/update far more than I'd realized — including a path toward forging a certificate. Nobody did it. But "nobody did it yet" is not a security model! So I stopped patching table by table and flipped the whole thing: -- kill the client's entire write surface, then grant back the ONE thing it needs ALTER DEFAULT PRI
AI 资讯
Spec-Driven Development: Let the Spec Drive the Code (With a Real Example)
By Sergio Colque Ponce — Software Engineering, Universidad Privada de Tacna. Full source code: github.com/srg-cp/spec-driven-development If you have used an AI coding agent — Copilot, Claude Code, Gemini CLI — you have probably lived this moment: you describe a feature, the agent produces code that compiles and looks right, and then it quietly does the wrong thing. The agent is not weak; the input was ambiguous. We have been treating coding agents like search engines when they behave more like very literal pair programmers. Spec-Driven Development (SDD) is the answer to that problem: instead of jumping straight to code, you write down what you want and why , refine it, and only then let the implementation follow. The specification — not the code — becomes the center of the project. What Spec-Driven Development actually is The idea is old (anyone who has written a Product Requirements Document will recognize it), but it has become practical again thanks to tools like GitHub's open-source Spec Kit . Spec Kit organizes the work into a small set of Markdown artifacts, each feeding the next: Constitution — the non-negotiable principles of the project (security rules, coding standards, architectural constraints). Spec — what you are building and why , with no implementation detail. Plan — the technical blueprint derived from the spec (stack, structure, decisions). Tasks — the plan broken into small, ordered, verifiable steps. Implement — the agent (or you) builds the tasks, with the previous artifacts as structured context. The workflow is usually summarized as Spec → Plan → Tasks → Implement , and the same process is meant to work regardless of language, framework, or which of the 30+ supported agents you use. The real shift is not "more documents." It is this: when requirements change, you update the spec, regenerate the plan, and let the implementation follow — instead of patching code and hoping the intent survives. The spec is a living artifact, not a dusty Word file
AI 资讯
Build vs Buy Software: A Decision Framework for Growing Businesses
The build-vs-buy question gets answered wrong in both directions. Scrappy teams build things they should have bought, wasting six months reinventing Stripe. Enterprise teams buy things they should have built, ending up with a duct-taped stack of ten SaaS products that cost more than a full-stack engineer. The real answer depends on five questions most decision frameworks don't ask. This guide is a practical walkthrough for anyone trying to figure out the right call for their own business. The Myth That Distorts Every Build-vs-Buy Conversation "Buying is cheaper." This is the default assumption, and it's wrong often enough to be dangerous. Buying looks cheaper because the cost is monthly instead of upfront -- a psychological trick, not an economic one. Run the numbers on any SaaS tool over 5 years and you'll usually find the cost lands within 2x of building custom. Sometimes below. The real cost difference is not price; it's time, flexibility, and ownership. When you buy: You spend less today, more in year 3 You get speed now, rigidity later You trade money for control You own none of the code When you build: You spend more today, less per year You trade speed now for flexibility later You trade money for control You own the code and can change anything Both are rational trades. The question is which one matches the stage and strategy of your business. When Buying Wins Start with the easy case. Buy off-the-shelf when: 1. The problem is generic and solved. Email hosting, payment processing, accounting, HR payroll, customer support tickets, video conferencing, file storage. These are solved problems. Building your own is nearly always the wrong call. 2. The space has mature competitive options. If there are 5 reputable companies competing on price and features, you benefit from that competition. Building custom takes you out of it. 3. Your process is standard. If you do exactly what every other company in your vertical does, a tool built for every company in your verti
开源项目
r4b1t_h0l3
→ Try it: gnomeman4201.github.io/r4b1t It's a curated random link generator for security and OSINT...
科技前沿
Carvana launches its first test drive center at a dealership, with more to come
Carvana is converting old car dealerships into test drive centers.
AI 资讯
Google bets on Gemini to reinvent the smart home speaker
Google is betting generative AI can breathe new life into the smart speaker. The company's new $99.99 Google Home Speaker replaces the rigid commands of the Google Assistant era with more conversational Gemini interactions.
AI 资讯
Extending Filament exports with Laravel Excel
Filament's export action is great. It's quick to set up, supports queued exports, includes column mapping, handles notifications, and keeps a history of generated files through the Export model. For most use cases, it's exactly what you need. But I recently ran into a limitation that the native export couldn't solve. When XLSX isn't really Excel I was exporting financial data or measurements from a Filament table. The export worked. The file downloaded. Excel opened it without any issue. The problem was that every amount was exported as text instead of a real numeric value. For an accountant, that creates several problems immediately: Excel formulas such as =SUM() don't work correctly Selecting a range of cells doesn't display totals in Excel's status bar Conditional formatting based on numeric values becomes unreliable Additional manual cleanup is required before the file can be used Technically the export contained the data. Practically, it wasn't usable. The root cause is simple: Filament's export system is designed around CSV-style exports. That's perfect for many scenarios, but it doesn't expose the full spreadsheet capabilities offered by PhpSpreadsheet and Laravel Excel . On top of that, I also had a second, completely different requirement: a yearly report with one worksheet per month, merged headers, borders, conditional formatting, and custom layouts. Not a table dump but a report. Why not just use Laravel Excel directly? Laravel Excel already solves all of these problems. It's built on PhpSpreadsheet and provides complete control over cell types, number formats, formulas, styling, and multiple worksheets. The obvious solution would have been to abandon Filament's export action entirely and build custom exports from scratch. But that means losing everything Filament already provides: Export modal and options form Column mapping UI Queue handling Progress notifications Download links Export model history I didn't want to rebuild all of that. I simply wanted
AI 资讯
Your Ticket Was Closed. The User Still Couldn't Pay.
Your backend returned 200. The mobile app showed an error. The user tapped "Pay" three times. Three pending charges hit their account. One order was placed. Their balance was short. And your incident log showed zero failures. Every engineer on the team did their job. Nobody solved the problem. This is the most common way engineering teams fail, not through incompetence, but through excellent execution of the wrong unit of work. And until you recognise the difference between completing a task and solving a business problem , you will keep shipping systems that work perfectly and experiences that don't. The Ticket-Thinker vs. The System-Owner Most engineers early in their careers think in tickets. Ticket assigned → code written → tests pass → PR merged → ticket closed. Done. This is fine when you're learning. It's a liability when you're trying to grow. The engineer who closes tickets is useful. The engineer who asks "what problem does this ticket actually solve, and am I solving it in the right place?" that engineer is dangerous in the best way. Here's the distinction in practice. The backend engineer builds a payment endpoint. It processes charges correctly, returns the right status codes, has proper error handling. 100% test coverage. Ticket closed. The mobile engineer builds the payment screen. It calls the endpoint, handles the response, shows confirmation or error. Smooth UI. Ticket closed. The problem nobody owned: what happens when the network drops after the backend processes the charge but before the mobile app receives the confirmation? The backend: charge processed. No error. The mobile: timeout. Shows "Payment failed." User retries. The user: charged twice. Both engineers solved their assigned problem correctly. The business problem — charge the user once and confirm it reliably — went unsolved. Because that problem lived in the space between their tickets, and nobody was watching that space. Real Scenario 1: The Payment That Worked and Failed at the Same
AI 资讯
I Built an Image Compressor That Runs 100% in the Browser
Most "compress your image" websites upload your photo to a server. You don't need one. The browser's own canvas can re-encode an image at any quality — I built a drag-and-drop compressor in about 30 lines , and your photo never leaves your machine. 🗜️ Try it (drop a photo): https://dev48v.infy.uk/solve/day9-image-compressor.html 1. Catch the dropped file — locally drop . addEventListener ( " drop " , e => { e . preventDefault (); const file = e . dataTransfer . files [ 0 ]; // stays in the tab, 0 bytes uploaded loadImage ( file ); }); For sensitive images (IDs, screenshots), "never uploaded" is a real feature, not just a nicety. 2. Decode it into an <img> A dropped file is just bytes. Load it via a local blob: URL: const img = new Image (); img . src = URL . createObjectURL ( file ); await img . decode (); 3. Draw it onto a canvas Now the browser holds the raw pixels, detached from the original file format: canvas . width = img . naturalWidth ; canvas . height = img . naturalHeight ; canvas . getContext ( " 2d " ). drawImage ( img , 0 , 0 ); 4. Re-encode at a quality (this IS the compression) canvas . toBlob ( blob => { preview . src = URL . createObjectURL ( blob ); showSize ( blob . size ); }, " image/jpeg " , 0.7 ); // 0.7 = 70% quality JPEG and WebP are lossy — they discard detail the eye barely notices. That third argument is the entire compression dial; a small quality drop often halves the file size. 5. Hand the result back as a download link . href = URL . createObjectURL ( blob ); link . download = " compressed.jpg " ; // the browser saves it, no server The takeaway FileReader → Image → Canvas → toBlob is a surprisingly powerful local image pipeline. The same four steps do resizing, format conversion, cropping, watermarking — all client-side, all private. A whole category of "image tools" needs no backend at all. Open it and drop a photo.
开发者
In Toy Story 5, the problem really is these damn phones (and tablets)
The Toy Story franchise began with a story about a vintage doll feeling threatened by the arrival of an electronic action figure. Woody and Buzz's rivalry embodied a shift that was happening in the '90s as children's toys were becoming more technologically sophisticated, and while toys have gotten even more tech-focused in the years since, […]
AI 资讯
Agentic eCommerce with Shopify and Sanity
Turbo Start Aisle is our agentic e-commerce starter on Shopify and Sanity. Instead of filters...
AI 资讯
The Gemini-Powered Google Home Speaker Is Finally Here
Arriving six years after Google’s last smart speaker, the new HomePod-style device was redesigned to play host to Gemini’s chatbot.
AI 资讯
The AI reality check: feeds are flooded, agents are costly, buyers are cooling
If you build with AI, three stories this week rhyme into one theme: the hype is colliding with the bill. Here's the builder's read on each — and what I'd actually do about it. 1. Most of a new TikTok feed is now AI slop A Kapwing study reported by Tubefilter hand-checked 10,742 videos across 20 categories and found that 59% of what a brand-new TikTok account sees is AI-generated . Kids content was the worst — 57% slop, with the #CartoonKids tag hitting 97% — and TikTok serves roughly 3x more slop than YouTube. Why builders should care: generation is now free and infinite, so volume is worthless as a moat. The scarce thing is taste and verification. If your product or content can be faked by a feed of bots, it will be. Polish, point of view, and "a human clearly did this" are the new differentiators. 2. Databricks grew 80% — but agents are eating its margins Per CNBC , Databricks' annualized revenue jumped about 80% to ~$6.9B, and its AI products now bring in $1.7B (up from $1.4B). The catch: the CEO says gross margin "will go lower" as customers run more agents. Why builders should care: this is the quiet tax of agentic software. An agent that loops, retries, and calls tools burns far more tokens than a single API call. If you're shipping agents, budget for inference at scale , not the sticker price on the pricing page. Profitability now lives in prompt efficiency, caching, and knowing when not to call the model. 3. 60% of US consumers are turned off by "AI" branding A WordPress VIP survey of 2,000 people, covered by TechCrunch , found that 60% reject "AI" in brand messaging , while 86% still want to check the original sources behind a claim. Why builders should care: "Now with AI!" is starting to read like a warning label. Sell the outcome, not the technology — "2x faster," "fewer errors," "your data stays private" — and cite where your results come from. Trust is becoming a feature you ship, not a slogan you bolt on. The takeaway Feeds are flooded, agents are cost
AI 资讯
The Slot-Machine Was the Point
Lars Faye's Agentic Coding Is a Trap — published Sunday, May 3, picked up on Hacker News at 398 points and 316 comments — is the best single compendium of the cognitive-debt evidence base anyone has put together in 2026. It catalogues the studies. It names the trade-offs. It lands on a personal-discipline conclusion. The receipts are now collected; the careful reader will have spent the weekend nodding through them. Buried in Faye's second paragraph, almost in passing, is the line that does the actual analytical work. Faye describes the agentic workflow as a process in which "someone defines the project's requirements ... generates a plan, and then pulls the slot machine lever over and over, iterating and reiterating with often multiple agent instances until it's done." The link goes to a March post by Quentin Rousseau, CTO and co-founder of Rootly, titled One More Prompt: The Dopamine Trap of Agentic Coding. The metaphor isn't Faye's. Rousseau got there first, in clinical language: the workflow runs on "variable ratio reinforcement — the same psychological mechanism that makes slot machines the most addictive form of gambling" . That is the framing the rest of Faye's piece is downstream of, and it is the framing this article is about. What the receipts add up to Faye's catalogue, briefly. Anthropic's own research note on internal use names what it calls the "paradox of supervision" : effective use of Claude requires the very skills that sustained Claude use atrophies. MIT Media Lab's Your Brain on ChatGPT measured the cognitive impact and labelled it cognitive debt . A Microsoft study covered by 404 Media reached parallel findings for knowledge workers more broadly. A separate Anthropic study on coding skills reported a 47% drop-off in debugging skills among engineers leaning heavily on AI-assisted workflows. Sandor Nyako, the LinkedIn engineering director who oversees fifty engineers, has reportedly asked his team not to use these tools for "tasks that require cri
AI 资讯
Why git pull --rebase should probably be your default
Most developers run git pull dozens of times a week without thinking about it. And most of the time, it works. Then one day you open a PR and the reviewer says "can you clean up the merge commits?" You look at your branch and see three "Merge branch 'main' into feature/login" commits scattered through history. The feature itself is 5 commits. The log is a mess. That mess comes from one decision: using git pull instead of git pull --rebase . Here's what's actually happening, and why the rebase variant produces cleaner history for teams. The setup: diverged history You're working on feature/login . You commit two changes locally ( X , Y ). Meanwhile, your teammate pushes two commits to main ( C , D ). Your branch and main have now diverged . Neither is a strict superset of the other. Git needs to reconcile them when you pull. Shared history: A → B Your local: A → B → X → Y (you added X, Y) Remote main: A → B → C → D (teammate added C, D) Git has two strategies for this reconciliation. Strategy 1: git pull (merge) A plain git pull creates a merge commit that joins your local history with the remote. Your commits and the remote's commits both appear in the log, connected by a merge node. The git log reads: M Merge branch 'main' into feature/login D fix: timeout on slow connections Y feat: client-side validation C chore: upgrade eslint X feat: login form B (shared) A (shared) This is honest history — it records exactly what happened: parallel development that was joined at a specific point. But it's also noisy history — the merge commit has no meaningful changes, and the log interleaves commits that weren't conceptually related. Strategy 2: git pull --rebase With --rebase , Git takes a different approach. It: Temporarily sets aside your local commits ( X , Y ) Fast-forwards your branch to the tip of the remote ( D ) Replays your commits on top, one by one, creating new commits ( X' , Y' ) The git log reads: Y' feat: client-side validation X' feat: login form D fix: timeo
AI 资讯
Got Thread problems? There’s an app for that
The new Thread Networks Diagnostics Tools app from Thread Group, the standards body behind the wireless IoT protocol, officially launches in beta today. The app, which arrives on iOS and has been available on Android in alpha for a few weeks, is the first dedicated tool to provide visibility into your Thread-based smart home network. […]
开发者
git diff on JSON is mostly noise. So I built a structural diff.
You change one value in a JSON config, run git diff , and get a wall of red and green — because a formatter reflowed the file, or the serializer reordered the keys, or the indentation shifted by two spaces. The one thing you actually changed is buried in there somewhere. Good luck finding it in review. The problem is that git diff and diff work on lines . JSON isn't lines — it's a tree. So I built jdelta : it compares the data , ignores key order and whitespace entirely, and tells you exactly which values changed, addressed by path. Zero dependencies, no network. What it looks like $ jdelta config.before.json config.after.json Added (1) + features.darkMode true Changed (2) ~ auth.required true → false ~ server.port 8080 → 3000 +1 -0 ~2 auth.required flipped to false and you can see it instantly — no scrolling past 200 lines of reindented braces. Why not git diff / diff ? Because they diff text. Run a formatter, sort your keys, change two spaces of indent, and a line differ lights up the whole file while reporting zero semantic change. jdelta parses both sides and walks the trees: Object keys show as user.profile.age ; array elements as items[2].price . Odd keys fall back to quoted brackets ( ["order-id"] ). A key on only one side is added / removed ; a key on both with a different value is changed . A type change ( number → string , object → array ) is one changed entry tagged with the kinds — not a confusing add + remove. Reordered keys and whitespace produce nothing , because they aren't data changes. Great for reviewing config changes, API-response snapshots, tsconfig / settings.json , lockfile-adjacent files, and test fixtures. In scripts and CI jdelta a.json b.json --json # machine-readable: {added, removed, changed, summary} jdelta a.json b.json --quiet # just the +a -r ~c line jdelta a.json b.json --exit-code # exit 1 if they differ — gate a pipeline on it Install npx jdelta a.json b.json # Node build (npm) pip install jdelta # Python build — same behavior Tw
AI 资讯
UUID v4 vs UUID v7: Performance, Security and Real Benchmarks at 100M
TL;DR — UUID v7 trie 13× plus vite que v4 en simulation B-tree (1M entrées), expose une empreinte mémoire identique, mais révèle son timestamp d'émission. UUID v4 reste le choix "zéro réflexion" pour les identifiants isolés. Le reste de cet article vous donnera les données pour décider. Introduction Les UUIDs sont omniprésents dans les systèmes modernes : clés primaires de bases de données, identifiants de sessions, tokens de traçabilité. Pourtant, le choix de la version impacte directement les performances en écriture et en lecture, la fragmentation des index, et — dans certains contextes — la confidentialité des données. UUID v4 (RFC 4122, 2005) est aujourd'hui la version par défaut de presque tous les ORM et frameworks. UUID v7 (RFC 9562, 2024) est son successeur moderne, conçu pour corriger son principal défaut : le désordre lexicographique. Dans cet article, nous allons mettre les deux en face avec des benchmarks réels sur des volumes de 100 000 à 10 millions d'UUIDs , analyser leur structure bit par bit, et vous donner une grille de décision claire. Structure interne : ce que contiennent ces 128 bits UUID v4 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx Bits Contenu 0–47 Aléatoire 48–51 Version (0100 = 4) 52–63 Aléatoire 64–65 Variant (10) 66–127 Aléatoire 122 bits d'entropie pure. Aucune information temporelle. Chaque UUID est statistiquement indépendant des autres. UUID v7 019ed5c8-2a2f-7974-91f2-6ba1f313dcfa └──────────────┘ 48 bits = timestamp Unix en millisecondes Bits Contenu 0–47 Timestamp Unix (ms) 48–51 Version (0111 = 7) 52–63 Aléatoire (sub-ms ou compteur) 64–65 Variant (10) 66–127 Aléatoire 74 bits d'entropie + 48 bits de temps. Naturellement monotone : deux UUIDs générés dans la même milliseconde sont toujours distincts et ordonnés de façon cohérente. Lecture du timestamp (Python) : import uuid6 u = uuid6 . uuid7 () b = u . bytes ts_ms = int . from_bytes ( b [: 6 ], ' big ' ) # → 1781703125553 (ms depuis epoch Unix) Depuis la sortie de nos benchmarks : [00