AI 资讯
How I Built Pakistan's Stock Market Education Platform as a Solo Trader-Developer
I am a full time trader and part time developer based in Karachi, Pakistan. A year ago I sat down to research how to properly compare brokers on the Pakistan Stock Exchange. Three hours later I had 11 browser tabs open, two of which had broken links, one had data from 2019, and none of them had everything I needed in one place. So I built PSX Pulse. What PSX Pulse Is PSX Pulse is a free stock market education platform for Pakistani retail investors. Everything a beginner needs to start investing in Pakistan's stock market — in one place. What is live right now: 35 verified SECP-licensed brokers with full contact details Complete mutual funds directory across 15 AMCs DCA calculator with realistic return scenarios 30-day beginner learning path Islamic investing guide PSX sector guide covering 12 sectors IPO tracker 100-term searchable glossary Weekly market recap every Friday All free. No login required. Live at: https://psxpulse.xwen.com.pk/ The Stack React + Tailwind CSS for the frontend. Vercel for hosting — free tier handles everything comfortably. No backend for most features — localStorage and static data keeps it fast and simple. Newsletter handled via a serverless Vercel function writing to a private GitHub CSV. What I Learned Building This Solo 1. The information gap in emerging markets is enormous Pakistani investors are not underserved because nobody cares. They are underserved because nobody with the technical skills to build tools also has the market knowledge to know what those tools should do. Being both a trader and a developer turned out to be the actual unfair advantage. 2. Free tools beat content for SEO My DCA calculator and broker directory pages get more consistent Google clicks than any article I have written. Tools solve a specific search intent that AI overviews do not replace — people still need to interact with a calculator, not just read about one. 3. Building in public is uncomfortable but worth it Sharing what you are building before it i
AI 资讯
What is the Forge Method? Five rules so your agents stop improvising.
In the first post I told you the story: 20 years as a developer, six months of being scared of AI, $800 in burned tokens, and a stubborn agent named Claudio who taught me — by failing over and over — how to ask for things properly. This post is the method that came out of all that pain. Five rules, one per letter of FORGE. I want to be honest about one thing up front: this is not a framework I invented at a whiteboard. Every rule here is a scar. Each one is the lesson from a specific mistake that cost me money, time, or sleep. I'm going to tell you the mistake first, and then the rule. Because the rule only makes sense once you've felt the pain that created it. Let's go. First, the idea behind all of it Here's the thing nobody told me when I started: A task is not a post-it. It's a contract. When you ask an AI agent for something with no structure, you're not giving an order — you're placing a bet. The agent interprets, assumes, improvises, and the result depends on how much context it managed to reconstruct on its own. Sometimes it guesses right. Often it doesn't. And you only find out after the tokens are gone. The Forge Method is the agreement between you and your agents: you bring the structure, they execute with precision . That's it. Five rules to hold up your end of that contract. F — Focused The mistake: My early tasks had titles like "Fix bug" and "Update stuff." I'd come back twenty minutes later to find the agent had fixed a bug — just not the one I meant. It wasn't wrong. It just had no way of knowing which thing I was talking about. **The rule: **If the title is vague, the task is vague. Vague in, vague out. A focused title needs a domain, an action, and a scope. Two words minimum, and no generic placeholders. ❌ Rejected: - "Fix bug" - "Update auth" - "Do the thing" ✅ Accepted: - "Fix authentication timeout on Nginx reverse proxy" - "Update JWT expiry from 1h to 24h in src/auth/config.ts" The test: Read the title with no context. Do you know the domain,
AI 资讯
How I Rebuilt My Entire User Feedback Workflow with FeedLog (And Why I Ditched Canny)
Six months into running my SaaS, my "feedback system" was three browser tabs, a starred Gmail folder, and a sticky note on my monitor that said "check Discord." That was the whole system. It held together until the day I found a three-paragraph email from a paying user — a genuinely detailed feature request with a real use case — sitting unread for 24 days. His last line was: "Happy to pay more if you can support this." I replied the same afternoon I found it. His reply: "Switched last week, thanks anyway." That was the moment I stopped treating feedback management as a nice-to-have. Why the usual fixes didn't fix anything I tried the obvious things first. I want to document them because I see a lot of people cycling through the same failed solutions. Notion database 🪦 Built a beautiful one. Color-coded tags, priority columns, status tracking. It lasted 11 days before nobody — including me — was maintaining it. The friction of "open Notion, find the right database, fill in six fields" is invisible when you're designing the system and fatal when you're in the middle of a support conversation. Airtable form 🪦 Better entry point, still disconnected from where users actually were when they had feedback. Nobody bookmarks your Airtable form. They DM you on Discord and you think "I'll add that later" and you don't. Canny — this one actually worked, for a while I genuinely liked Canny. Clean interface, users could upvote requests, I could see what was popular. It felt like a real system. Then our user count grew and the pricing tier jumped. I was looking at $99/month for a feedback board for a product still finding its footing. That's not a moral judgment on Canny — it's a fair product — but for a bootstrapped indie dev, it started feeling like a tax on momentum. The deeper problem with all three solutions was the same: they were inboxes, not loops. User submits → enters the void → user never knows if anyone saw it → user assumes nobody did → trust erodes → churn. I had bui
AI 资讯
Why my single Next.js app runs 4 different domains (and how the proxy.ts decides who sees what)
> TL;DR — I run four different domains off one Next.js codebase: a marketing site at pagestrike.com , an authenticated app at app.pagestrike.com, a public publishing domain at pagestrike.app, and customer-owned domains. The trick isn't deploying four apps — it's a single proxy.ts that reads the host and rewrites/redirects/passes-through per-request. This post walks through why I chose this shape, the parts I got wrong, and the cookie-domain trick that makes it all stick. Stack: Next.js 16 App Router , Supabase , Vercel , one proxy.ts file (~370 lines). This is the second post in my build-in-public series on PageStrike . Last week I wrote about the 6-CTA architecture — modeling conversion intent as a discriminated union so one launch could be a checkout, a COD form, or a calendar booking. This post is about a different primitive: modeling host as routing context so one codebase can serve four very different audiences. Why four domains, not one Most SaaS apps live at one domain — say myapp.com with /dashboard under it. That works until you grow into edge cases that don't fit: Marketing pages get spammed by your own dashboard headers. Your marketing nav says "Sign in / Pricing / Blog". Your dashboard nav says "Launches / Contacts / Settings". You either A/B them with conditional logic everywhere or you live with the noise. Public user-generated pages share your domain reputation. When a customer publishes a landing page at myapp.com/p/[slug] , every spammy LP from a free-tier user drags down myapp.com 's sender reputation, search trust, and ad-account standing. Google and Meta penalize the host, not the path. Custom domains don't route cleanly. A customer who buys acmewidgets.com and points it at your app expects their LP at acmewidgets.com/ — not myapp.com/p/acme-widgets . You need a rewrite that's transparent to the visitor, doesn't 404 on _next/static/* , and survives RSC prefetches. I split PageStrike — a free AI landing page builder — across four hosts to solve al
AI 资讯
I Deployed My Go Backend to a Real VPS. Here's Exactly What Happened.
In Part 14 , I finished HMAC webhook signing. The backend was complete — JWT auth, PostgreSQL, Redis caching, rate limiting, circuit breaker, worker pool, webhook delivery, migrations, Docker. All running locally. But "runs on my machine" isn't a portfolio project. It's a homework assignment. Time to ship it. The Stack Being Deployed Go backend — ~15MB Docker image (multi-stage build, CGO_ENABLED=0) PostgreSQL 16 — with golang-migrate running schema migrations on startup Redis — for caching, rate limiting, and refresh token storage Oracle Cloud Free Tier — 1GB RAM, 45GB disk, already provisioned Everything wired together with docker-compose.yml . One command to start the entire stack. Step 1: The VM Was Fine, Actually I was worried about the free tier specs. Turned out the "1GB" in the tier name refers to RAM, not disk. The actual disk is 45GB — plenty. free -h # 954MB RAM, 552MB available df -h # 45GB disk, 41GB free The real constraint: no swap . Go's compiler is memory-hungry. Without swap, building the Docker image on the VM would exhaust RAM and kill the process. More on this in a moment. Step 2: Install Docker curl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker ubuntu newgrp docker The official install script handles everything — Docker Engine, containerd, Docker Compose plugin. One command, done. Step 3: Clone the Repo The repo is private. Created a fine-grained GitHub personal access token with Contents: Read-only permission. Used it to clone: git clone https://TOKEN@github.com/absep98/Go_learn.git Security note: never paste tokens in chat, email, or anywhere visible. Type them directly into the terminal. Tokens in chat history are compromised tokens. Step 4: Create the .env File The .env from my local machine needed two changes for Docker: # LOCAL (wrong for Docker): DB_HOST = localhost REDIS_HOST = localhost # DOCKER (correct): DB_HOST = postgres # ← service name in docker-compose.yml REDIS_HOST = redis # ← service name in docker-compose.ym