2025-12-01 00:32:26
I recently attended GOTO conference in Copenhagen (https://gotocph.com/2025, you can find the slides for some of the presentations there) and would like to share some of the interesting topics. This topic is going to be the last one.
The presenters shared very interesting story about the future we planned and the future we are going to have. Here are the main points and my comments as well.
The future was meant to be for everyone, but we landed in the place where it is actually for the few with unevenly distributed resources - yes, one can look at UNICEF report (https://data.unicef.org/resources/sofi-2025/) to see that 8.3 percent of global population faced hunger in 2024. The food is the basic need of the human and it is somehow not possible to provide it for the acceptable rate which should be like 99,9 % of the population.
The future tends to bring more infrastructure and information networks so that everything and everyone become more connected - I agree, we can see this is happening: we are connecting with the people using various social networks, we can travel quickly all over the world. The companies create customer experience which bases on all the online and possibly offline activities to be so close as virtual friend or maybe closer. They are able to gather huge amount of data and turn it into large income.
I am just not sure if this is the right direction, do we really want to be more connected with people and the business? Did anyone ask? I am sceptical, I can think of the scenario that we are heading towards digital crowd where everyone is just too close to each other.
We should still however have hope and excitement looking into it - Yes we should, I especially like the Mars colonisation idea. It seems it doesn't have much sense, it is extremly hard, but because of this it is exciting for sure.
The change is more late, gradual and cumulative than we think - These are tips on how to think about the future in general. We can use them when trying to foresee the evolution of quantum computing, genes edition, internet of things or other future technologies mentioned for example here: https://www.sciencenewstoday.org/the-future-of-technology-what-will-the-next-decade-bring.
As I see it, in my environment, there is not enough discussion about the future. I rarely can read anything in the news, I know that nobody teaches about it in the schools. We as the society are living in the past and only sometimes plan for the very near future. The Status Quo is the king.
The only exceptions are literature and movies but I feel like it is not taken seriously by the people, it is just the entertainment. I am sure we should be more aware about the processes which take place around us nowadays and plan more for the distant future as well to know at least the general direction we would like to follow.
2025-12-01 00:23:23
Backblaze B2 and Cloudflare R2 are both object storage services that people often consider as affordable and flexible alternatives to AWS S3. Although they look similar, each service has its own strengths and ideal use cases.
If you are building something heavily file based such as an image hosting service, static asset delivery, or a backup system, choosing the right storage solution can save a lot of money and improve performance.
Backblaze B2 is excellent when your storage needs focus on low cost pricing and large volumes of data that are not accessed very frequently.
Common scenarios where B2 works really well:
• Database and server backups
• Long term archiving and cold storage
• Server logs, large documents, older data
• Internal storage without global delivery needs
• Large files for backend pipelines
In short, if your priority is cheap storage, Backblaze B2 is often the first choice.
You can check the official B2 pricing here:
👉 https://www.backblaze.com/cloud-storage/pricing
Cloudflare R2 is ideal for applications that frequently access files, require low latency, and serve users globally.
Common use cases for R2:
• Web assets such as images, fonts, JavaScript, and CSS
• Image hosting and public file delivery
• File based APIs
• Applications running on Cloudflare Workers
• Systems that need global traffic delivery without expensive egress costs
The biggest advantage of R2 is zero egress fees, which completely changes the cost structure for public facing applications.
You can find the full pricing for R2 here:
👉 https://developers.cloudflare.com/r2/pricing
My platform ImgPeek is a free image hosting service that allows users to upload and share images quickly. Because the service is public and images are frequently accessed, choosing the right storage layer is crucial.
Why ImgPeek chose Cloudflare R2:
• Images are fetched often, which means egress would be very high
• With R2, egress cost is zero, making operational costs much more predictable
• Automatically integrated with Cloudflare’s global CDN for fast delivery
• Works seamlessly with Cloudflare Workers for extra edge processing
• Financially safer for a free service like image hosting
If ImgPeek used Backblaze B2, the egress cost would grow quickly as traffic increased.
| Category | Backblaze B2 | Cloudflare R2 |
|---|---|---|
| Primary Focus | Large, low cost storage | Global file delivery and active apps |
| Storage Pricing | Cheaper per GB | Slightly more expensive |
| Egress Cost | Charges apply | Zero |
| Global Performance | Depends on region | Integrated with Cloudflare CDN |
| Edge Compute Integration | None | Native with Cloudflare Workers |
| Ideal for Public Traffic | Less ideal due to egress fees | Extremely ideal |
| Ideal for Large Files | Very suitable | Still works but not the main strength |
| S3 Compatible | Yes | Yes |
| Ideal Use Cases | Backups, archives, cold data | Web assets, image hosting, file APIs |
If you need cheap storage for backups or archives, choose Backblaze B2.
If you are building a public application that frequently serves files and you want to avoid egress costs, choose Cloudflare R2, just like ImgPeek did.
2025-12-01 00:18:20
I am so glad that I have took some time out of my day to tryout this Kiroween hackathon. A little bit of background, I have been building apps on Atlassian ecosystem for quite a number of years already. Therefore, the advantage I had in this is my domain knowledge to build on this ecosystem.
Without further a due, here is the project that I have been working on.
Guess what, all these that you're seeing, it took me not more that 2 days of my weekend to vibe this out. It was also a surprise for me seeing how easy to build this on Kiro with spec driven approach if we have all the basic agent instructions and prompts setup.
To start Atlassian's forge project, you're need to install the @forge/cli. Feel free to get started here.
The key thing here is, when you bootstrap the project with forge create, you'll noticed that it comes with an AGENTS.md. Kiro treated this as the steering docs, which helped the agent so much when I am vibing and building the specs on Kiro.
The other things that wasn’t created by default, but I have added it is the Atlassian Forge MCP server. By just adding this to the mcp.json, we’re literally good to go.
{
"mcpServers": {
"forge-knowledge": {
"url": "https://mcp.atlassian.com/v1/forge/mcp",
"transport": "http"
}
}
}
Just like the Agents.md, everything works so seamlessly well together. The context of MCP helps the agent to stay in context when building the apps is what amaze me the most.
The original Agents.md has enforced with UI Kit for the frontend. However, knowing that I need to use custom React Flow library to achieve the amazing drag and drop flow, I need to use custom UI. And, with the small tweak to the Agents.md everything works nicely for me.
Kiro is such a fun tools to work with, and while this is the second time I am using it, the output seems to be much better when it initially launched.
With the integration of Agents, Steering Docs, Specs, and MCP. We’re able to be so much more effective to prevent hallucination and enjoy the process of working with AI to pair programming or vibe code.
2025-12-01 00:15:51
## Diferenças na História de Commits: Navegando pelo Passado e Presente do Seu Código
A história de commits é o coração pulsante do seu projeto. Ela conta a narrativa da evolução do seu código, desde a criação inicial até as iterações mais recentes. Dominar as diferenças na história de commits é crucial para entender, colaborar e manter um projeto de software saudável.
main ou master). Elas são essenciais para colaboração e experimentação.git log: Exibe o histórico de commits, incluindo IDs de commit, autores, datas e mensagens.
git log --oneline: Uma versão compacta, ideal para uma visão geral rápida.git log -p: Mostra as diferenças (patches) de cada commit.git log --graph: Visualiza a história de commits como um gráfico, mostrando branches e merges.git diff: Compara as diferenças entre commits, branches, arquivos ou até mesmo o código atual e o que está no stage.
git diff <commit1> <commit2>: Compara dois commits específicos.git diff <branch1> <branch2>: Compara as diferenças entre duas branches.git diff --staged: Mostra as alterações que foram adicionadas à área de stage.git diff -- <arquivo>: Mostra as diferenças de um arquivo específico.Conflitos ocorrem quando duas branches (ou commits) modificam a mesma parte de um arquivo de forma incompatível. O Git não consegue decidir qual alteração manter, então o conflito deve ser resolvido manualmente.
Passos para Resolver Conflitos:
<<<<<<<, ======= e >>>>>>>.git add) e crie um novo commit para resolver o conflito.Dicas para Evitar Conflitos:
Existem diversos fluxos de trabalho para gerenciar seu código. A escolha depende da sua equipe, projeto e preferências.
main. Bom para projetos menores e colaboração rápida.main e integram suas alterações com frequência. Requer testes automatizados e uma forte disciplina de código.Considerações:
Dominar a história de commits e os fluxos de trabalho é essencial para qualquer desenvolvedor. Ao entender as diferenças na história, resolver conflitos e escolher o fluxo de trabalho certo, você e sua equipe podem colaborar de forma mais eficiente, manter o código limpo e entregar projetos de sucesso. Explore as ferramentas, experimente diferentes fluxos e encontre o que funciona melhor para você!
2025-12-01 00:12:36
A deep dive into building secure, scalable user registration with React, FastAPI, and modern authentication patterns
User registration is the gateway to any application. It's the first interaction users have with your system, and it sets the tone for security, user experience, and architectural quality. In this article, I'll walk you through the complete user registration flow in my AI Email Assistant application, from the moment a user clicks "Register" to when their encrypted credentials are safely stored in the database.
We'll explore:
The registration flow spans multiple layers of abstraction, each with a specific responsibility:
Frontend Stack:
Backend Stack:
Before diving into the details, let's visualize the high-level journey:
Figure 1: High-level sequence diagram of the registration process
Key Steps:
One of the key architectural decisions in this application is the separation of concerns on the frontend. Instead of making direct API calls from UI components, the registration flow passes through three distinct layers:
This architecture provides several benefits:
Figure 2: Frontend architecture showing the flow from UI component through Context and API clients to the backend
The registration page is a client-side React component that manages form state and user interaction.
// webapp/frontend/app/auth/register/page.tsx
export default function RegisterPage() {
const router = useRouter();
const { register } = useAuth(); // Custom hook from AuthContext
const [formData, setFormData] = useState({
email: '',
first_name: '',
last_name: '',
password: '',
confirmPassword: '',
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// Client-side validation
const validationError = validateForm();
if (validationError) {
setError(validationError);
return;
}
try {
// Call register from context - clean and simple!
await register({
email: formData.email,
first_name: formData.first_name,
last_name: formData.last_name,
password: formData.password,
});
// Auto-login successful, redirect to dashboard
router.push('/accounts');
} catch (err: any) {
setError(err.message || 'Registration failed');
}
};
}
Key Observations:
register()
The Auth Context is where the magic happens. It's a React Context Provider that manages global authentication state and provides auth functions to all components.
// webapp/frontend/components/auth/auth-context.tsx
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
/**
* Register new user and auto-login
*/
const register = useCallback(async (data: RegisterData) => {
setIsLoading(true);
try {
// Step 1: Register user
await authClient.register(data);
// Step 2: Auto-login after successful registration
await login({ email: data.email, password: data.password });
} catch (error) {
setIsLoading(false);
throw error;
}
}, [login]);
return (
<AuthContext.Provider value={{ user, register, login, logout }}>
{children}
</AuthContext.Provider>
);
}
// Custom hook for easy access
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
}
Why Use Context?
Why Wrap Context in a Custom Hook (useAuth)?
The useAuth() custom hook is a convenience wrapper around useContext(AuthContext). It has the CONSUMER which can consume the AuthContext PROVIDER. While we could use useContext(AuthContext) directly in components, the custom hook provides several advantages:
useAuth() instead of useContext(AuthContext) - shorter and more semanticAuthProvider, catching mistakes earlyuseRouter, useTheme)Example:
// Without custom hook (verbose, no error checking)
const context = useContext(AuthContext);
if (!context) throw new Error('...');
const { register } = context;
// With custom hook (clean, safe)
const { register } = useAuth();
This pattern is so common in React that it's considered a best practice for any Context API.
The API client layer is split into two files:
auth-client.ts - Authentication-specific API calls:
export const authClient = {
register: async (data: RegisterData): Promise<void> => {
await api.post('/api/auth/register', data);
},
login: async (credentials: LoginCredentials): Promise<AuthTokens> => {
// OAuth2 password flow
const formData = new URLSearchParams();
formData.append('username', credentials.email);
formData.append('password', credentials.password);
const response = await fetch(/* ... */);
const tokens = await response.json();
// Store JWT token
tokenManager.set(tokens.access_token);
return tokens;
},
};
api-client.ts - Base HTTP client with automatic token injection:
// BLOCK 1
export async function apiClient<T>(
endpoint: string,
options: RequestOptions = {}
): Promise<T> {
const config: RequestInit = {
method: options.method || 'GET',
headers: {
'Content-Type': 'application/json',
...options.headers,
},
};
// Auto-inject JWT token for protected endpoints
if (options.requiresAuth) {
const token = getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
}
const response = await fetch(`${API_BASE_URL}${endpoint}`, config);
// Centralized error handling
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Request failed');
}
return response.json();
}
// BLOCK 2
// ❌ WITHOUT apiClient - Repetitive nightmare
async function getUser() {
const token = localStorage.getItem('auth_token');
const response = await fetch('http://localhost:8000/api/users/me', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Request failed');
}
return response.json();
}
async function updateUser(data) {
const token = localStorage.getItem('auth_token');
const response = await fetch('http://localhost:8000/api/users/me', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify(data),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Request failed');
}
return response.json();
}
// ... repeat this 50 times for every endpoint
// BLOCK 3
// ✅ WITH apiClient - Clean and reusable
async function getUser() {
return apiClient('/api/users/me', { requiresAuth: true });
}
async function updateUser(data) {
return apiClient('/api/users/me', {
method: 'PUT',
requiresAuth: true,
body: data
});
}
Benefits of using the apiClient:
The backend follows a clean Router → Service → Database pattern:
This separation ensures that business logic is decoupled from HTTP concerns, making it easier to test and maintain.
Figure 3: Backend architecture showing the flow from API endpoint through validation, service layer, and database operations
The router is the entry point for HTTP requests. It defines the endpoint and delegates to the service layer.
# webapp/backend/auth/router.py
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
router = APIRouter(prefix='/auth', tags=['auth'])
@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register_user(
db: Annotated[Session, Depends(get_db)],
register_user_request: schemas.RegisterUserRequest
):
"""
Register a new user
- **email**: Valid email address (must be unique)
- **first_name**: User's first name
- **last_name**: User's last name
- **password**: User's password (will be hashed)
"""
service.register_user(db, register_user_request)
return {"message": "User registered successfully"}
Key Features:
Pydantic schemas define the shape and validation rules for request data.
# webapp/backend/auth/schemas.py
from pydantic import BaseModel, EmailStr
class RegisterUserRequest(BaseModel):
"""Request model for user registration"""
email: EmailStr
first_name: str
last_name: str
password: str
What Pydantic Does:
[email protected])If validation fails, FastAPI automatically returns a 422 Unprocessable Entity response with details about what went wrong.
The service layer contains the core registration logic, including password hashing and database operations.
# webapp/backend/auth/service.py
from passlib.context import CryptContext
from uuid import uuid4
bcrypt_context = CryptContext(schemes=['bcrypt'], deprecated='auto')
def get_password_hash(password: str) -> str:
"""Hash a plain password using bcrypt"""
return bcrypt_context.hash(password)
def register_user(db: Session, register_user_request: schemas.RegisterUserRequest):
"""
Register a new user
Raises UserAlreadyExistsError if email is already registered
"""
try:
# Create User model with hashed password
create_user_model = User(
id=uuid4(), # Generate unique UUID
email=register_user_request.email,
first_name=register_user_request.first_name,
last_name=register_user_request.last_name,
password_hash=get_password_hash(register_user_request.password)
)
# Add to database and commit
db.add(create_user_model)
db.commit()
logging.info(f"Successfully registered user: {register_user_request.email}")
except IntegrityError:
# Email already exists (UNIQUE constraint violation)
db.rollback()
raise UserAlreadyExistsError()
Critical Security Feature: bcrypt Password Hashing
The password is never stored in plain text. Instead, it's hashed using bcrypt:
Input: "securepass123"
Output: "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYzS7eFa.oi"
Why bcrypt?
The User model defines the database table structure.
# webapp/backend/entities/users.py
from sqlalchemy import Column, String, DateTime, UUID
from datetime import datetime, timezone
class User(Base):
__tablename__ = 'users'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
email = Column(String, unique=True, nullable=False)
first_name = Column(String, nullable=False)
last_name = Column(String, nullable=False)
password_hash = Column(String, nullable=False)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime(timezone=True), onupdate=lambda: datetime.now(timezone.utc))
# Relationships
email_accounts = relationship("EmailAccount", back_populates="user", cascade="all, delete-orphan")
Database Constraints:
Security is implemented at multiple layers:
1. Frontend Validation
2. Backend Validation
3. Password Security
4. SQL Injection Prevention
5. Token Security
The system handles errors gracefully at every layer:
HTTP 400 Bad Request
{
"detail": "User with this email already exists"
}
HTTP 422 Unprocessable Entity
{
"detail": [
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
}
HTTP 422 Unprocessable Entity
{
"detail": [
{
"loc": ["body", "first_name"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
One of the UX improvements in this implementation is automatic login after registration. Here's how it works:
login() with the same credentials/accounts dashboardBenefits:
cd webapp/backend
uv run main.py
cd webapp/frontend
npm run dev
http://localhost:3000/auth/register
Fill Form:
[email protected]
Test
User
password123
password123
Verify:
sqlite3 webapp/backend/databse.db
SELECT id, email, first_name, last_name, created_at
FROM users
WHERE email = '[email protected]';
The bcrypt cost factor is set to 12, which provides a good balance:
The email field has a unique index for fast lookups:
CREATE UNIQUE INDEX idx_users_email ON users(email);
This ensures O(log n) search time for email lookups during login.
✅ Layered Architecture: Clean separation of concerns made the code maintainable and testable
✅ React Context: Global auth state eliminated prop drilling and simplified components
✅ Pydantic Validation: Automatic validation saved time and caught errors early
✅ bcrypt Hashing: Industry-standard security with minimal implementation effort
✅ Auto-Login: Improved UX significantly with minimal code
🔄 Add Unit Tests: Currently no automated tests for registration flow
🔄 Rate Limiting: Prevent brute-force registration attempts
🔄 Email Verification: Send confirmation email before activating account
🔄 Password Strength Meter: Visual feedback on password quality
🔄 CAPTCHA: Prevent automated bot registrations
Building a secure, user-friendly registration flow requires attention to detail at every layer of the stack. By following clean architecture principles, implementing security best practices, and focusing on user experience, we've created a registration system that is:
The key takeaway is that good architecture pays dividends. The three-layer frontend abstraction and the router-service-database pattern on the backend make the code easy to understand, test, and extend.
Whether you're building a simple side project or a production application, these patterns and practices will serve you well.
The complete source code for this implementation is available in my AI Email Coach project:
webapp/frontend/app/auth/register/
webapp/backend/auth/
webapp/backend/entities/users.py
Written by Nazmus Ashrafi | Built with Next.js, FastAPI, and ❤️
Full Source: Available in private repository upon request
Please contact me for access: [email protected]
2025-12-01 00:11:52
Si te has metido en el mundo del desarrollo web, sabes que crear una landing page moderna no se trata solo de que se vea bonita, sino de que funcione de verdad y convierta visitantes en clientes. Este módulo de Your.Code.Web es un recurso excelente porque no solo te enseña a maquetar con HTML, sino que se centra en los pilares fundamentales que a menudo se olvidan: la semántica y la accesibilidad.
Aquí no solo vas a ver etiquetas, sino la razón de ser de cada una. Te explican cómo usar correctamente los elementos de HTML5 —como header, main y footer— para que tu página no solo esté bien organizada, sino que los motores de búsqueda y los lectores de pantalla puedan entenderla perfectamente. Esto es crucial en la web actual.
Además, el curso desglosa la estructura ideal de cualquier landing exitosa: desde el impacto inicial del bloque "Hero" con su llamada a la acción, pasando por cómo presentar las características y los testimonios de forma eficaz. Y lo mejor de todo es que adoptan la mentalidad mobile-first. Esto significa que estás aprendiendo a construir la página pensando primero en el móvil, garantizando que tu diseño sea responsivo y rápido para cualquier usuario, lo cual es vital para no perder ventas. Si buscas llevar tus habilidades de maquetación al nivel profesional, este tipo de enfoque detallado en las buenas prácticas es justo lo que necesitas.