diff --git a/i18nConfig.js b/i18nConfig.js index 9a1df7dd..033d5586 100644 --- a/i18nConfig.js +++ b/i18nConfig.js @@ -1,5 +1,5 @@ const i18nConfig = { - locales: ['en', 'pt', 'ja'], + locales: ['en', 'pt-BR', 'pt-PT', 'ja'], defaultLocale: 'en', } diff --git a/package-lock.json b/package-lock.json index ccdd222c..5964a7a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -608,6 +608,126 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "license": "MIT", @@ -7527,126 +7647,6 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", - "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", - "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", - "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", - "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", - "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", - "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", - "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", - "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } } } diff --git a/src/app/[locale]/articles/atproto-for-distsys-engineers/pt.mdx b/src/app/[locale]/articles/atproto-for-distsys-engineers/pt-BR.mdx similarity index 100% rename from src/app/[locale]/articles/atproto-for-distsys-engineers/pt.mdx rename to src/app/[locale]/articles/atproto-for-distsys-engineers/pt-BR.mdx diff --git a/src/app/[locale]/articles/atproto-for-distsys-engineers/pt-PT.mdx b/src/app/[locale]/articles/atproto-for-distsys-engineers/pt-PT.mdx new file mode 100644 index 00000000..05a1cc59 --- /dev/null +++ b/src/app/[locale]/articles/atproto-for-distsys-engineers/pt-PT.mdx @@ -0,0 +1,232 @@ +import { Container } from "@/components/Container" +import { FooterCTA } from "@/components/FooterCTA" +import image1 from "./image1.png" +import image10 from "./image10.png" +import image11 from "./image11.png" +import image12 from "./image12.png" +import image13 from "./image13.png" +import image14 from "./image14.png" +import image15 from "./image15.png" +import image16 from "./image16.png" +import image17 from "./image17.png" +import image18 from "./image18.png" +import image19 from "./image19.png" +import image2 from "./image2.png" +import image20 from "./image20.png" +import image21 from "./image21.png" +import image22 from "./image22.png" +import image23 from "./image23.png" +import image24 from './image24.png' +import image3 from "./image3.png" +import image4 from "./image4.png" +import image5 from "./image5.png" +import image6 from "./image6.png" +import image7 from "./image7.png" +import image8 from "./image8.png" +import image9 from "./image9.png" + +export const metadata = { + title: 'ATProto para engenheiros de sistemas distribuídos', + description: + 'AT Protocol é a tecnologia desenvolvida na Bluesky para redes sociais abertas. Neste artigo vamos explorar o AT Proto do ponto de vista da engenharia de back-end distribuído.', +} + +# ATProto para engenheiros de sistemas distribuídos + +*3 de setembro de 2024* + +AT Protocol é a tecnologia desenvolvida na [Bluesky] (https://bsky.app) para redes sociais abertas. Neste artigo, vamos explorar o AT Protocol do ponto de vista da engenharia de back-end distribuído. {{className: 'lead'}} + +Se já construiu um back-end com [stream-processing](https://milinda.pathirage.org/kappa-architecture.com/), então já está familiarizado com o tipo de sistemas que vamos explorar. Se ainda não estiver, não se preocupe, iremos explicar-lhe tudo. {{className: 'lead'}} + +## Escalar o back-end tradicional da Web + +A clássica e feliz arquitetura da Web é a “grande base de dados SQL” por detrás do nosso servidor de aplicações. A aplicação comunica com a base de dados e lida com os pedidos do front-end. + + + + + +À medida que a nossa aplicação cresce atingimos alguns limites de desempenho, pelo que aplicamos alguma cache. + + + + + +Depois, digamos que escalamos a nossa base de dados horizontalmente através de "sharding" e réplicas. + + + + + +Isto é muito bom, mas estamos a construir uma rede social com centenas de milhões de utilizadores; ainda assim este modelo tem os seus limites. O problema é que a nossa base de dados SQL é “[strongly consistent](https://en.wikipedia.org/wiki/Strong_consistency)”, o que significa que o estado é mantido uniformemente e sincronizado em todo o sistema. Manter a consistência forte incorre num custo de desempenho que se torna o nosso gargalo. + +Se aliviarmos o nosso sistema para utilizar “[eventual consistency](https://en.wikipedia.org/wiki/Eventual_consistency)”, podemos escalar muito mais. Começamos por mudar para um cluster NoSQL. + + + + + +Isto é melhor para escalar mas sem SQL torna-se mais difícil construir as nossas consultas. Acontece que as bases de dados SQL têm muitas funcionalidades úteis, como as consultas JOIN e de agregação. De facto, a nossa base de dados NoSQL é apenas um armazenamento de valores chave. Escrever funcionalidades torna-se uma dor de cabeça! + +Para resolver isso precisamos de criar vistas pré-computadas do nosso conjunto de dados. Estas vistas são essencialmente como consultas em cache. Até duplicamos os dados canónicos nestas visualizações para que sejam mais rápidas. + +Vamos chamar-lhes os nossos servidores de visualização. + + + + + +Agora percebemos que manter os nossos servidores de visualização sincronizados com os dados canónicos no cluster NoSQL é complicado. Por vezes, os nossos servidores de exibição falham e perdem atualizações. Precisamos de garantir que as nossas exibições permanecem atualizadas de forma confiável. + +Para resolver este problema, introduzimos um registo de eventos (como o [Kafka](https://kafka.apache.org/)). Esse registo regista e transmite todas as alterações ao cluster NoSQL. Os nossos servidores de visualização escutam — e reproduzem — esse registo para garantir que nunca perdem uma atualização, mesmo quando estes precisam de reiniciar. + + + + + +Chegámos agora a uma [stream processing architecture] (https://milinda.pathirage.org/kappa-architecture.com/) e, embora existam mais pormenores que se poderiam abordar, isto será suficiente por agora. + +A boa notícia é que esta arquitetura escala muito bem. Abdicámos de uma consistência forte e, por vezes, as nossas consultas de leitura ficam aquém da versão mais actualizada dos dados mas o serviço não deixa de escrever nem entra num estado incorreto. + +De certa forma, o que fizemos foi construir uma base de dados à medida, [turning it inside-out] (https://www.youtube.com/watch?v=fU9hR3kiOK0). Simplificámos o armazenamento canónico num cluster NoSQL e construímos o nosso próprio motor de consulta com os servidores de visualização. É menos conveniente na sua construção, mas é escalável. + +## Descentralizar o nosso back-end de alta escala + +O objetivo do AT Protocol é interligar aplicações de modo a que os seus back-ends partilhem o estado, incluindo contas de utilizador e conteúdos. + +Como podemos fazer isso? Se olharmos para o nosso diagrama, podemos ver que a maior parte do sistema está isolado do mundo exterior, com apenas o servidor de aplicações a fornecer uma interface pública. + + + + + +O nosso objetivo é quebrar este isolamento para que outras pessoas possam juntar-se ao nosso cluster NoSQL, ao nosso registo de eventos, aos nossos servidores de visualização, etc. + +Eis como vai ficar: + + + + + +Cada um destes serviços internos é agora um serviço externo. Eles têm APIs públicas que qualquer pessoa pode consumir. Para além disso, qualquer pessoa pode criar as suas próprias instâncias destes serviços. + +O nosso objetivo é fazer com que qualquer pessoa possa contribuir para este back-end descentralizado. Isso significa que não queremos apenas um cluster NoSQL, ou um servidor View. Queremos muitos desses servidores a trabalhar em conjunto. Então, na verdade, é mais ou menos assim: + + + + + +Então, como é que fazemos com que todos estes serviços funcionem em conjunto? + +## Unificação do modelo de dados + +Vamos estabelecer um modelo de dados partilhado chamado [“user data repository.”](/guias/data-repos) + + + + + +Cada repositório de dados contém documentos JSON a que chamaremos “registos”. + + + + + +Para efeitos de organização dividimos estes registos em “colecções”. + + + + + +Agora vamos opinar sobre os nossos serviços NoSQL para que todos eles usem este modelo [data repository](/guias/data-repos). + + + + + +Lembre-se: os serviços de repositório de dados continuam a ser basicamente armazéns NoSQL, só que agora estão organizados de uma forma muito específica: + +1. Cada utilizador tem um repositório de dados. +2. Cada repositório possui colecções. +3. Cada coleção é um armazenamento K/V ordenado por documentos JSON. + +Uma vez que os repositórios de dados podem ser alojados por qualquer pessoa, temos de lhes dar [URLs](/specs/at-uri-scheme). + + + + + +Já agora, vamos também criar um [whole URL scheme](/specs/at-uri-scheme) para os nossos registos. + + + + + +Ótimo! Além disso, uma vez que vamos sincronizar estes registos na Internet seria uma boa ideia assiná-los criptograficamente para sabermos que são autênticos. + + + + + +## Mapear o fluxo de dados + +Agora que configurámos o nosso back-end descentralizado de alta escala, vamos mapear como uma aplicação funciona realmente no ATProto. + +Uma vez que estamos a criar uma nova aplicação vamos querer duas coisas: um servidor de aplicações (que aloje a nossa API e front-end) e um servidor de visualização (que recolhe dados da rede para nós). Muitas vezes, juntamos os servidores de aplicação e de visualização, pelo que podemos chamar-lhe apenas “Appview”. Vamos começar por aqui: + + + + + +Um utilizador inicia sessão na nossa aplicação utilizando o OAuth. No processo, diz-nos qual o servidor que aloja o seu repositório de dados e dá-nos permissão para ler e escrever no mesmo. + + + + + +Começámos bem — podemos ler e escrever documentos JSON no repositório do utilizador. Se o utilizador já tiver dados de outras aplicações (como um perfil) também podemos ler esses dados. Se estivéssemos a construir uma aplicação para um único utilizador já teríamos terminado. + +Mas vamos ver o que acontece quando escrevemos um documento JSON. + + + + + +Isto faz o commit do documento para o repositório e cria um registo nos registos de eventos que estão a escutar o repositório. + + + + + +A partir daí, o evento é enviado para quaisquer serviços de visualização que estejam a escutar — incluindo o nosso! + + + + + +Por que é que estamos a ouvir o fluxo de eventos se somos nós que estamos a fazer a escrita? Porque não somos os únicos a fazer registos! Existem muitos repositórios de utilizadores que geram eventos e muitas aplicações que registam para eles! + + + + + +Assim, podemos ver uma espécie de fluxo de dados circular em todo o nosso back-end descentralizado, com registos a serem confirmadas nos repositórios de dados e depois emitidos através dos registos de eventos para os servidores de visualização, onde podem ser lidos pelas nossas aplicações. + + + + + +E (espera-se) que esta rede continue a crescer: não apenas para aumentar a capacidade mas para criar uma maior variedade de aplicações partilhadas nesta rede aberta de aplicações. + + + + + +## Criar sistemas abertos práticos + +O AT Protocol funde a tecnologia p2p com práticas de sistemas de alta escala. Os nossos engenheiros fundadores eram engenheiros de base do [IPFS](https://en.wikipedia.org/wiki/InterPlanetary_File_System) e do [Dat](https://en.wikipedia.org/wiki/Dat_(software)), e Martin Kleppmann — o autor de [Data Intensive Applications](https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/) — é um consultor técnico ativo. + +Antes de iniciarmos a Bluesky estabelecemos um requisito claro de “não dar passos para trás”. Queríamos que a rede fosse tão conveniente e global como todas as aplicações sociais anteriores, sem deixar de funcionar como uma rede aberta. É por isso que ao olhar para a federação e para as cadeias de blocos, os limites de escala dessas arquitecturas sobressaíram para nós. A nossa solução foi adotar práticas padrão para back-ends de alta escala e, posteriormente, aplicar as técnicas que utilizámos em sistemas peer-to-peer para criar uma rede aberta. + + \ No newline at end of file diff --git a/src/app/[locale]/guides/account-lifecycle/pt-PT.mdx b/src/app/[locale]/guides/account-lifecycle/pt-PT.mdx new file mode 100644 index 00000000..a742414e --- /dev/null +++ b/src/app/[locale]/guides/account-lifecycle/pt-PT.mdx @@ -0,0 +1,52 @@ +export const metadata = { + title: 'Eventos do ciclo de vida da conta', + description: + 'Melhores práticas do ciclo de vida da conta', +} + +# Melhores práticas do ciclo de vida da conta + +Este documento complementa a especificação [Account Hosting](/specs/account), que fornece uma visão geral de alto nível dos ciclos de vida da conta. Resume os comportamentos esperados para algumas transições comuns do ciclo de vida da conta e quais os eventos de firehose esperados e em que ordem. Em geral, espera-se que o software seja resistente à transmissão parcial ou incorrecta de eventos. + +**Criação de uma nova conta:** quando uma conta é registada num PDS e é criada uma nova identidade (DID). + +- o PDS gerará ou confirmará a existência da identidade da conta (DID e identificador). Quando o DID estiver num estado confirmado que possa ser resolvido por outros serviços na rede e apontar para a instância atual do PDS, o PDS emite um evento `#identity`. É bom, mas não obrigatório, esperar até que o identificador possa ser resolvido por terceiros antes de emitir o evento (especialmente, mas não só, se o PDS estiver a fornecer um identificador para a conta). O estado da conta pode ou não ser “ativo” quando este evento é emitido. +- uma vez que a criação da conta tenha sido completada o PDS responderá com `active` aos pedidos da API para o estado da conta, um evento `#account` pode ser emitido +- quando o repositório da conta é inicializado com um `rev` e `commit`, uma mensagem `#commit` pode ser emitida. O repositório inicial pode estar “vazio” (sem registos) ou pode conter registos. +- a ordem específica dos eventos não é formalmente especificada, mas a ordem recomendada é: `#identity`, `#account`, `#commit` +- os serviços downstream processam e passam por estes eventos + +A **Migração de contas:** é descrita de seguida de forma mais detalhada, mas os eventos e comportamentos relevantes são: + +- o novo PDS não emitirá qualquer evento aquando da criação inicial da conta. O estado da conta será `deactivated` no novo PDS (que responderá como tal aos pedidos API) +- quando a identidade é actualizada e confirmada pelo novo PDS, este deve emitir um evento `#identity` +- quando a conta é mudada para `active` no novo PDS, este deve emitir um evento `#account` e um evento `#commit`; a ordem não é formalmente necessária, mas recomenda-se que o evento `#account` seja feito primeiro. Idealmente o evento `#commit` estará vazio (sem novos registos) mas assinado com qualquer nova chave de assinatura. E terá um `rev` novo/incrementado. +- quando a conta é desactivada no PDS antigo, este deve emitir um evento `#account`, indicando que a conta está inativa e tem o estado `deactivated`. +- Os retransmissores devem ignorar os eventos `#account` e `#commit` que não são provenientes da instância do PDS declarada atualmente para a identidade: estes não devem ser passados para o firehose de saída. Além disso, eles devem ignorar eventos `#commit` quando o status da conta local não for `active`. No geral, isso significa que a migração de contas deve resultar em três eventos vindos do relay: um `#identity` (do novo PDS), um `#account` (do novo PDS), e um `#commit` (do novo PDS). A `#account` do antigo PDS é normalmente ignorada. +- Serviços downstream (por exemplo, AppView) devem atualizar seu cache de identidade e incrementar o `rev` da conta (quando o `#commit` é recebido), mas de outra forma não será necessário tomar nenhuma ação. + +**Eliminação de conta:** + +- O PDS emite um evento `#account`, com `active` false e status `deleted`. +- O Relay atualiza o status da conta local para o repo e passa pelo evento `#account`. Se o Relay é um espelho completo, ele irá parar imediatamente de servir `getRepo`, `getRecord` e requisições API similares para a conta, indicando a razão no erro de resposta. O Relay pode apagar totalmente o conteúdo do repositório localmente de acordo com a política local. A janela de backfill do firehose não precisa ser imediatamente limpa de eventos de commit para o repo desde que a janela de backfill seja limitada por tempo. +- o PDS não deve emitir eventos `#commit` para uma conta que não esteja “ativa”. Se mais alguma mensagem `#commit` for emitida para o repositório (por exemplo, por acidente ou processamento ou entrega fora de ordem), todos os serviços downstream devem ignorar o evento e não o transmitir +- os serviços downstream (por exemplo, AppView) devem parar imediatamente de servir/distribuir conteúdo para a conta. Podem adiar a eliminação permanente dos dados de acordo com a política local. A atualização de agregações (por exemplo, contagens de registos) pode também ser adiada ou processada numa fila de espera em segundo plano de acordo com a política e a implementação. As mensagens de estado de erro podem indicar que o conteúdo “desapareceu” (existia, mas já não está disponível) ou que o conteúdo “não foi encontrado” (não revelando que o conteúdo existia anteriormente) + +A remoção de contas funciona de forma semelhante à eliminação de contas. + +**Desativação de conta:** + +- O PDS emite um evento `#account`, com `active` false e status `deactivated`. +- Semelhante à eliminação, o Relay processa o evento, pára de redistribuir o conteúdo e passa pelo evento. O Relay não deve limpar totalmente o conteúdo localmente, embora possa eventualmente apagar cópias locais se o status de desativação persistir por um longo tempo (de acordo com a política local). +- semelhante à eliminação, eventos `#commit` não devem ser emitidos pelo PDS e devem ser ignorados e não repassados se recebidos pelos Relays +- os serviços downstream (por exemplo, AppViews) devem tornar o conteúdo indisponível mas não precisam de apagar os dados localmente. Devem indicar o estado da conta/conteúdo como “indisponível”; a melhor prática é indicar especificamente que tal se deve à desativação da conta. + +A suspensão da conta funciona de forma semelhante à desativação. + +**Reativação de conta:** + +- O PDS emite um evento `#account`, com o estado `active`. +- O Relay verifica que a reativação da conta é válida, por exemplo, que veio da instância atual do PDS para a identidade. Actualiza o estado da conta local e transmite o evento. +- quaisquer serviços downstream (por exemplo, AppViews) devem atualizar o estado da conta local para a conta. +- qualquer serviço que não tenha qualquer conteúdo de repositório atual para a conta (por exemplo, porque foi anteriormente eliminado) pode ir buscar uma exportação CAR de repositório e processá-la como uma tarefa em segundo plano. Um host “upstream” (como um relay) pode ter uma cópia do repo, ou o serviço pode se conectar diretamente ao host PDS da conta. Eles não são obrigados a fazer isso e podem esperar por um evento `#commit`. +- se a conta foi previamente excluída ou ficou inativa por um longo tempo, é uma boa prática para o PDS emitir um evento `#commit` vazio após a reativação para garantir que os serviços downstream estejam sincronizados diff --git a/src/app/[locale]/guides/applications/pt.mdx b/src/app/[locale]/guides/applications/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/applications/pt.mdx rename to src/app/[locale]/guides/applications/pt-BR.mdx diff --git a/src/app/[locale]/guides/data-repos/pt.mdx b/src/app/[locale]/guides/data-repos/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/data-repos/pt.mdx rename to src/app/[locale]/guides/data-repos/pt-BR.mdx diff --git a/src/app/[locale]/guides/faq/pt.mdx b/src/app/[locale]/guides/faq/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/faq/pt.mdx rename to src/app/[locale]/guides/faq/pt-BR.mdx diff --git a/src/app/[locale]/guides/glossary/pt.mdx b/src/app/[locale]/guides/glossary/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/glossary/pt.mdx rename to src/app/[locale]/guides/glossary/pt-BR.mdx diff --git a/src/app/[locale]/guides/identity/pt.mdx b/src/app/[locale]/guides/identity/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/identity/pt.mdx rename to src/app/[locale]/guides/identity/pt-BR.mdx diff --git a/src/app/[locale]/guides/lexicon/pt.mdx b/src/app/[locale]/guides/lexicon/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/lexicon/pt.mdx rename to src/app/[locale]/guides/lexicon/pt-BR.mdx diff --git a/src/app/[locale]/guides/overview/pt.mdx b/src/app/[locale]/guides/overview/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/overview/pt.mdx rename to src/app/[locale]/guides/overview/pt-BR.mdx diff --git a/src/app/[locale]/guides/self-hosting/pt.mdx b/src/app/[locale]/guides/self-hosting/pt-BR.mdx similarity index 100% rename from src/app/[locale]/guides/self-hosting/pt.mdx rename to src/app/[locale]/guides/self-hosting/pt-BR.mdx diff --git a/src/app/[locale]/guides/self-hosting/pt-PT.mdx b/src/app/[locale]/guides/self-hosting/pt-PT.mdx new file mode 100644 index 00000000..94181383 --- /dev/null +++ b/src/app/[locale]/guides/self-hosting/pt-PT.mdx @@ -0,0 +1,168 @@ +export const metadata = { + title: 'Auto-hospedagem', + description: + 'Auto-hospedar um PDS Bluesky significa gerir o seu próprio servidor de dados pessoais, capaz de se federar com a rede ATProto mais alargada.', +} + +# Auto-hospedagem + +Auto-hospedar um PDS Bluesky significa gerir o seu próprio servidor de dados pessoais, capaz de se federar com a rede ATProto mais alargada. {{className: 'lead'}} + +## Índice + +* [Preparação para a auto-hospedagem do PDS](#preparation-for-self-hosting-pds) +* [Abra a firewall da sua nuvem para HTTP e HTTPS](#open-your-cloud-firewall-for-http-and-https) +* [Configurar o DNS para o seu domínio](#configure-dns-for-your-domain) +* [Verificar se o DNS está a funcionar como esperado](#check-that-dns-is-working-as-expected) +* [Instalador no Ubuntu 20.04/22.04 e Debian 11/12](#installer-on-ubuntu-20-04-22-04-and-debian-11-12) +* [Verificar se o seu PDS está online e acessível](#verifying-that-your-pds-is-online-and-accessible) +* [Criar uma conta utilizando pdsadmin](#creating-an-account-using-pdsadmin) +* [Criar uma conta utilizando um código de convite](#creating-an-account-using-an-invite-code) +* [Utilizar a aplicação Bluesky com o seu PDS](#using-the-bluesky-app-with-your-pds) +* [Atualização do PDS](#updating-your-pds) +* [Obter ajuda](#getting-help) + + +## Preparação para auto-hospedagem do PDS + +Aceder a um servidor de qualquer fornecedor de serviços de nuvem, [Digital Ocean](https://digitalocean.com/) e [Vultr](https://vultr.com/) são duas escolhas populares. + +Certifique-se de que pode aceder ao seu servidor através do ssh e de que tem acesso à root. + +**Requisitos do servidor** +* Endereço IPv4 público +* Nome DNS público +* Acesso público de entrada à Internet permitido nas portas 80/tcp e 443/tcp + +**Recomendações de servidores.** +| | | +| ----------------------- | ------------ | +| Sistema Operativo | Ubuntu 22.04 | +| Memória (RAM) | 1 GB | +| CPU Cores | 1 | +| Armazenamento | 20 GB SSD | +| Arquiteturas | amd64, arm64 | +| Número de utilizadores | 1-20 | + +**Nota:** É uma boa prática de segurança restringir o acesso ssh de entrada (porta 22/tcp) ao endereço IP público do seu próprio computador. Pode verificar o seu endereço IP público atual utilizando [ifconfig.me](https://ifconfig.me/). + +## Abra a firewall da sua nuvem para HTTP e HTTPS + +Uma das causas mais comuns de má configuração é não abrir corretamente as portas da firewall. Certifique-se de que verifica novamente este passo. + +Na consola do seu fornecedor de serviços na nuvem, as seguintes portas devem estar abertas para o acesso de entrada a partir da Internet pública. + +* 80/tcp (Utilizado apenas para a verificação da certificação TLS) +* 443/tcp (Utilizado para todos os pedidos de aplicação) + +**Nota:** não é necessário configurar o TLS ou redirecionar os pedidos da porta 80 para a 443 porque o servidor Web Caddy, incluído no ficheiro Docker compose, tratará disso por si. + +## Configurar o DNS para o seu domínio + +A partir do painel de controlo do seu fornecedor de DNS, configure um domínio com registos que apontem para o seu servidor. + +| Name | Type | Value | TTL | +| --------------- | ---- | ------------- | --- | +| `exemplo.com` | `A` | `12.34.56.78` | 600 | +| `*.exemplo.com` | `A` | `12.34.56.78` | 600 | + +**Nota:** +* Substitua `exemplo.com` pelo seu nome de domínio. +* Substitua `12.34.56.78` pelo endereço IP do seu servidor. +* Alguns fornecedores podem utilizar o símbolo `@` para representar a root do seu domínio. +* O registo wildcard é necessário para permitir que os utilizadores criem novas contas no seu PDS. +* O TTL pode ser qualquer coisa, mas 600 (10 minutos) é razoável + +## Verificar se o DNS está a funcionar como esperado + +Utilize um serviço como [DNS Checker](https://dnschecker.org/) para verificar se consegue resolver nomes de domínio. + +Exemplos a verificar (tipo de registo `A`): +* `exemplo.com` +* `aleatorio.exemplo.com` +* `teste123.exemplo.com` + +Todos eles devem retornar o IP público do seu servidor. + +## Instalador no Ubuntu 20.04/22.04 e Debian 11/12 + +No seu servidor, através de ssh, descarregue o script de instalação utilizando o wget: + +```bash +wget https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh +``` + +ou descarregue-o utilizando curl: + +```bash +curl https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh >installer.sh +``` + +Depois execute o instalador usando o bash: + +```bash +sudo bash installer.sh +``` + +## Verificar se o seu PDS está online e acessível + +> [!DICA] +Os problemas mais comuns com a obtenção de conteúdo PDS consumido na rede ao vivo ocorrem quando as pessoas substituem a configuração Caddy fornecida por nginx, apache ou proxies reversos semelhantes. Obter certificados TLS, WebSockets e nomes de servidores virtuais corretos pode ser complicado. No momento, não estamos fornecendo suporte técnico para outras configurações. +Pode verificar se o seu servidor está online e saudável solicitando healthcheck endpoint. + +Pode aceder a `https://exemplo.com/xrpc/_health` no seu navegador. Deverá ver uma resposta JSON com uma versão, como: + +``` +{"version":"0.2.2-beta.2"} +``` + +Também é necessário verificar se os WebSockets estão a funcionar para que o resto da rede receba o conteúdo do seu PDS. Você pode testar instalando uma ferramenta como `wsdump` e executar o seguinte comando: + +```bash +wsdump "wss://exemplo.com/xrpc/com.atproto.sync.subscribeRepos?cursor=0" +``` + +Note que não existirá saída de eventos no WebSocket até que eles sejam criados no PDS, portanto, o comando acima indicado pode continuar a ser executado sem saída se as coisas forem configuradas com sucesso. + +## Criar uma conta com pdsadmin + +Utilizando o ssh no seu servidor, utilize `pdsadmin` para criar uma conta caso ainda não o tenha feito. + +```bash +sudo pdsadmin account create +``` + +## Criar uma conta utilizando um código de convite + +Utilizando o ssh no seu servidor, utilize o `pdsadmin` para criar um código de convite. + +```bash +sudo pdsadmin create-invite-code +``` + +Ao criar uma conta utilizando a aplicação, introduza este código de convite. + +## Utilizar a aplicação Bluesky com o seu PDS + +Pode utilizar a aplicação Bluesky para ligar ao seu PDS. + +1. Descarregar a aplicação Bluesky + * [Bluesky na Web](https://bsky.app/) + * [Bluesky para iPhone](https://apps.apple.com/us/app/bluesky-social/id6444370199) + * [Bluesky para Android](https://play.google.com/store/apps/details?id=xyz.blueskyweb.app) +1. Introduza o URL do seu PDS (ex: `https://exemplo.com/`) + +_Nota: como o certificado TLS do subdomínio é criado sob demanda, pode levar de 10 a 30 segundos para que seu identificador fique acessível. Se não estiver a ver a sua primeira mensagem/perfil, aguarde 30 segundos e tente fazer outra mensagem._ + +## Atualização do PDS + +Recomenda-se que mantenha o seu PDS atualizado com as novas versões, caso contrário, as coisas podem falhar. Pode utilizar a ferramenta `pdsadmin` para atualizar o seu PDS. + +```bash +sudo pdsadmin update +``` + +## Obter ajuda + +- [Visite o GitHub](https://github.com/bluesky-social/pds) para problema e discussões. +- [Junte-se ao Discord dos administradores do Protocolo AT PDS](https://discord.gg/e7hpHxRfBP) para conversar com outras pessoas que alojam instâncias e obter actualizações importantes sobre a distribuição PDS. diff --git a/src/app/[locale]/pt.mdx b/src/app/[locale]/pt-BR.mdx similarity index 98% rename from src/app/[locale]/pt.mdx rename to src/app/[locale]/pt-BR.mdx index cf476de6..3b865a0f 100644 --- a/src/app/[locale]/pt.mdx +++ b/src/app/[locale]/pt-BR.mdx @@ -34,9 +34,9 @@ O Protocolo AT é uma rede aberta e descentralizada para a construção de aplic - + - + ## Saber mais diff --git a/src/app/[locale]/pt-PT.mdx b/src/app/[locale]/pt-PT.mdx new file mode 100644 index 00000000..a2623820 --- /dev/null +++ b/src/app/[locale]/pt-PT.mdx @@ -0,0 +1,75 @@ +import { ArticleSummary, ArticleSummarySmall } from '@/components/ArticleSummary' +import { CodeCard } from '@/components/CodeCard' +import { Firehose } from '@/components/Firehose' +import { Guides } from '@/components/Guides' +import { HeroPattern } from '@/components/HeroPattern' +import { UserIcon } from '@/components/icons/UserIcon' +import { ImageCard } from '@/components/ImageCard' +import { Specs } from '@/components/Specs' +import DotMediaInterviewPng from '@/images/media/dotmedia-interview.png' +import HowDoesBlueskyWorkBlogpostPng from '@/images/media/how-does-bsky-work-blogpost.png' +import WebWithoutWallsPng from '@/images/media/web-without-walls.png' +import WhitepaperPng from '@/images/media/whitepaper.png' + +export const metadata = { + title: 'AT Protocol', + description: + 'O AT Protocol é uma rede aberta, descentralizada e de elevado desempenho para a criação de aplicações sociais.', +} + +export const sections = [] + + + +# Bem-vindo à Atmosfera + +O AT Protocol é uma rede aberta e descentralizada para a criação de aplicações sociais. {{ className: 'lead' }} + +
+ + +
+ + + + + +## Saber mais + +
+ + + O que é um PDS? um AppView? um DID? Se se sente um pouco confuso com os novos conceitos leia este glossário. + + + + Neste guia, criamos uma aplicação multiusuário simples que publica o seu “status” atual como um emoji. + + + + Neste artigo, exploramos o ATProto na perspetiva da engenharia de back-end distribuído. + + + + Este guia irá apresentar-lhe o Lexicon e irá ajudá-lo no processo inicial de construção das suas próprias estruturas. + + +
+ +
+ + + + + + + +
+ +## Procura os documentos da API do Bluesky? + +Aceda a [docs.bsky.app](https://docs.bsky.app) para obter documentação específica do Bluesky. diff --git a/src/components/LanguageChanger.tsx b/src/components/LanguageChanger.tsx index e886b2d6..ebac5bcd 100644 --- a/src/components/LanguageChanger.tsx +++ b/src/components/LanguageChanger.tsx @@ -1,10 +1,9 @@ 'use client' -import { useRouter } from 'next/navigation' -import { usePathname } from 'next/navigation' import { useCurrentLocale } from 'next-i18n-router/client' -import i18nConfig from '../../i18nConfig' +import { usePathname, useRouter } from 'next/navigation' import { ChangeEvent } from 'react' +import i18nConfig from '../../i18nConfig' export default function LanguageChanger() { const currentLocale = useCurrentLocale(i18nConfig) @@ -37,7 +36,8 @@ export default function LanguageChanger() { className="block w-full appearance-none rounded-md border-0 py-1.5 pl-3 pr-3 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-indigo-600 sm:text-sm sm:leading-6 dark:bg-gray-800 dark:text-gray-100 dark:ring-gray-700" > - + + )