Compare commits

..

103 commits
main ... build

Author SHA1 Message Date
Forgejo actions[bot]
84963d136e Deploy 2025-04-08 2025-04-08 07:21:23 +00:00
Forgejo actions[bot]
f358f1dc80 Deploy 2025-04-07 2025-04-07 20:54:32 +00:00
Forgejo actions[bot]
e6f5b01a75 Deploy 2025-04-07 2025-04-07 07:15:34 +00:00
Forgejo actions[bot]
b57cc9f7ba Deploy 2025-04-06 2025-04-06 07:17:14 +00:00
Forgejo actions[bot]
03ca44a11e Deploy 2025-04-05 2025-04-05 19:13:34 +00:00
Forgejo actions[bot]
accea34e0b Deploy 2025-04-04 2025-04-04 17:13:48 +00:00
Forgejo actions[bot]
ba5a1d1fc7 Deploy 2025-04-04 2025-04-04 13:13:38 +00:00
Forgejo actions[bot]
a8c674f407 Deploy 2025-04-04 2025-04-04 10:17:03 +00:00
Forgejo actions[bot]
bef8c7684b Deploy 2025-04-04 2025-04-04 08:12:11 +00:00
Forgejo actions[bot]
47bc87966e Deploy 2025-04-04 2025-04-04 08:11:13 +00:00
Forgejo actions[bot]
77531ffb68 Deploy 2025-04-04 2025-04-04 07:20:33 +00:00
Forgejo actions[bot]
b03bd8d390 Deploy 2025-04-03 2025-04-03 21:13:22 +00:00
Forgejo actions[bot]
15620dd22c Deploy 2025-03-31 2025-03-31 19:10:33 +00:00
Forgejo actions[bot]
4f488c3f10 Deploy 2025-03-31 2025-03-31 18:09:56 +00:00
Forgejo actions[bot]
f053ef30b7 Deploy 2025-03-30 2025-03-30 07:14:28 +00:00
Forgejo actions[bot]
88c1915160 Deploy 2025-03-29 2025-03-29 12:20:54 +00:00
Forgejo actions[bot]
3cf2c9354d Deploy 2025-03-29 2025-03-29 08:09:08 +00:00
Forgejo actions[bot]
c466eb4283 Deploy 2025-03-27 2025-03-27 11:08:23 +00:00
Forgejo actions[bot]
87ac6fc13f Deploy 2025-03-27 2025-03-27 07:12:19 +00:00
Forgejo actions[bot]
9f7f346c44 Deploy 2025-03-26 2025-03-26 14:07:14 +00:00
Forgejo actions[bot]
508b8a5686 Deploy 2025-03-26 2025-03-26 07:25:59 +00:00
Forgejo actions[bot]
64487124d2 Deploy 2025-03-25 2025-03-25 23:37:45 +00:00
Forgejo actions[bot]
a308b26d64 Deploy 2025-03-25 2025-03-25 23:33:25 +00:00
Forgejo actions[bot]
ff15dbb916 Deploy 2025-03-24 2025-03-24 21:30:43 +00:00
Forgejo actions[bot]
db86ddd3a5 Deploy 2025-03-24 2025-03-24 09:09:00 +00:00
Forgejo actions[bot]
6f5de6ffa4 Deploy 2025-03-22 2025-03-22 14:39:17 +00:00
Forgejo actions[bot]
a9f90bf966 Deploy 2025-03-21 2025-03-21 00:46:45 +00:00
Forgejo actions[bot]
dbd5892ff6 Deploy 2025-03-20 2025-03-20 14:27:05 +00:00
Forgejo actions[bot]
4cf0673aab Deploy 2025-03-20 2025-03-20 12:17:24 +00:00
Forgejo actions[bot]
1c08e5afc5 Deploy 2025-03-20 2025-03-20 12:10:43 +00:00
Forgejo actions[bot]
fd0084741c Deploy 2025-03-20 2025-03-20 11:10:30 +00:00
Forgejo actions[bot]
42b98bfc28 Deploy 2025-03-20 2025-03-20 07:13:57 +00:00
Forgejo actions[bot]
c10b9c84ea Deploy 2025-03-16 2025-03-16 15:31:27 +00:00
Forgejo actions[bot]
d5f552c32b Deploy 2025-03-14 2025-03-14 13:07:29 +00:00
Forgejo actions[bot]
1c1817fde7 Deploy 2025-03-14 2025-03-14 12:06:59 +00:00
Forgejo actions[bot]
dc45555676 Deploy 2025-03-14 2025-03-14 08:08:01 +00:00
Forgejo actions[bot]
de9bafe08c Deploy 2025-03-13 2025-03-13 07:12:00 +00:00
Forgejo actions[bot]
b79037a12b Deploy 2025-03-12 2025-03-12 12:51:29 +00:00
Forgejo actions[bot]
960748846b Deploy 2025-03-12 2025-03-12 12:38:56 +00:00
Forgejo actions[bot]
dbb2002580 Deploy 2025-03-11 2025-03-11 07:29:25 +00:00
Forgejo actions[bot]
aaffe287f7 Deploy 2025-03-10 2025-03-10 21:55:46 +00:00
Forgejo actions[bot]
5fea726523 Deploy 2025-03-10 2025-03-10 07:18:34 +00:00
Forgejo actions[bot]
00d4c8ada1 Deploy 2025-03-09 2025-03-09 12:22:01 +00:00
Forgejo actions[bot]
c435f8ad84 Deploy 2025-03-09 2025-03-09 08:10:25 +00:00
Forgejo actions[bot]
f9d59072db Deploy 2025-03-09 2025-03-09 07:14:20 +00:00
Forgejo actions[bot]
8d2dc25e04 Deploy 2025-03-08 2025-03-08 07:28:58 +00:00
Forgejo actions[bot]
f3ab13214a Deploy 2025-03-07 2025-03-07 19:08:16 +00:00
Forgejo actions[bot]
5eb8988e11 Deploy 2025-03-07 2025-03-07 18:09:07 +00:00
Forgejo actions[bot]
ddf7b9ca58 Deploy 2025-03-06 2025-03-06 18:42:10 +00:00
Forgejo actions[bot]
7f27edef3f Deploy 2025-03-06 2025-03-06 07:12:08 +00:00
Forgejo actions[bot]
31e6f758fc Deploy 2025-03-05 2025-03-05 12:24:36 +00:00
Forgejo actions[bot]
ba4d315c44 Deploy 2025-03-05 2025-03-05 11:24:07 +00:00
Forgejo actions[bot]
e2c2da77b8 Deploy 2025-03-04 2025-03-04 11:15:38 +00:00
Forgejo actions[bot]
33adef66a8 Deploy 2025-03-04 2025-03-04 11:13:17 +00:00
Forgejo actions[bot]
c7374a3706 Deploy 2025-03-04 2025-03-04 10:21:42 +00:00
Forgejo actions[bot]
880cf4c0f1 Deploy 2025-03-04 2025-03-04 07:19:13 +00:00
Forgejo actions[bot]
3c1624f9a1 Deploy 2025-03-03 2025-03-03 22:33:32 +00:00
Forgejo actions[bot]
e75c6e8308 Deploy 2025-03-03 2025-03-03 21:34:27 +00:00
Forgejo actions[bot]
f55a8f16a3 Deploy 2025-03-03 2025-03-03 17:14:08 +00:00
Forgejo actions[bot]
8a10fed9b4 Deploy 2025-03-02 2025-03-02 07:35:15 +00:00
Forgejo actions[bot]
293afcde45 Deploy 2025-03-01 2025-03-01 15:34:50 +00:00
Forgejo actions[bot]
bc82068947 Deploy 2025-02-28 2025-02-28 13:19:39 +00:00
Forgejo actions[bot]
cb1cba8f60 Deploy 2025-02-28 2025-02-28 07:18:03 +00:00
Forgejo actions[bot]
285a35b22d Deploy 2025-02-27 2025-02-27 19:44:47 +00:00
Forgejo actions[bot]
f1fecdb047 Deploy 2025-02-27 2025-02-27 19:42:57 +00:00
Forgejo actions[bot]
3fae28f1b4 Deploy 2025-02-26 2025-02-26 19:16:16 +00:00
Forgejo actions[bot]
6df48c08ff Deploy 2025-02-26 2025-02-26 18:07:50 +00:00
Forgejo actions[bot]
f4cfb4486d Deploy 2025-02-26 2025-02-26 16:17:11 +00:00
Forgejo actions[bot]
2ff6fd9b52 Deploy 2025-02-26 2025-02-26 16:12:54 +00:00
Forgejo actions[bot]
d8f7be952d Deploy 2025-02-26 2025-02-26 14:23:13 +00:00
Forgejo actions[bot]
3b1dd25e88 Deploy 2025-02-26 2025-02-26 13:24:09 +00:00
Forgejo actions[bot]
221d160429 Deploy 2025-02-25 2025-02-25 07:34:17 +00:00
Forgejo actions[bot]
2dc14a4c7a Deploy 2025-02-24 2025-02-24 22:54:59 +00:00
Forgejo actions[bot]
d08279bae6 Deploy 2025-02-24 2025-02-24 21:29:57 +00:00
Forgejo actions[bot]
d1519601e9 Deploy 2025-02-20 2025-02-20 18:33:34 +00:00
Forgejo actions[bot]
85773c69b9 Deploy 2025-02-20 2025-02-20 18:31:26 +00:00
Forgejo actions[bot]
2ceae06a32 Deploy 2025-02-19 2025-02-19 22:28:03 +00:00
Forgejo actions[bot]
69931b8926 Deploy 2025-02-19 2025-02-19 14:13:41 +00:00
Forgejo actions[bot]
19773ee139 Deploy 2025-02-19 2025-02-19 13:11:37 +00:00
Forgejo actions[bot]
403d85acc8 Deploy 2025-02-18 2025-02-18 20:13:35 +00:00
Forgejo actions[bot]
afed1f486d Deploy 2025-02-18 2025-02-18 18:28:35 +00:00
Forgejo actions[bot]
7a75a2a74d Deploy 2025-02-18 2025-02-18 17:19:58 +00:00
Forgejo actions[bot]
cf6882e49c Deploy 2025-02-17 2025-02-17 07:35:32 +00:00
Forgejo actions[bot]
20f9afaee9 Deploy 2025-02-17 2025-02-17 07:34:25 +00:00
Forgejo actions[bot]
6430852cc1 Deploy 2025-02-16 2025-02-16 23:25:58 +00:00
Forgejo actions[bot]
ee23398f03 Deploy 2025-02-16 2025-02-16 22:12:50 +00:00
Forgejo actions[bot]
1fcda5b6a2 Deploy 2025-02-16 2025-02-16 14:23:13 +00:00
Forgejo actions[bot]
1cb4d9ef1a Deploy 2025-02-16 2025-02-16 07:31:07 +00:00
Forgejo actions[bot]
a2ad1109a8 Deploy 2025-02-14 2025-02-14 18:19:02 +00:00
Forgejo actions[bot]
05d33ffb08 Deploy 2025-02-14 2025-02-14 07:19:41 +00:00
Forgejo actions[bot]
3b819e4e8e Deploy 2025-02-13 2025-02-13 12:09:16 +00:00
Forgejo actions[bot]
a4d50d1419 Deploy 2025-02-12 2025-02-12 14:07:07 +00:00
Forgejo actions[bot]
b195b44165 Deploy 2025-02-12 2025-02-12 12:10:56 +00:00
Forgejo actions[bot]
f3620cacd1 Deploy 2025-02-10 2025-02-10 23:53:18 +00:00
Forgejo actions[bot]
ff436a144a Deploy 2025-02-10 2025-02-10 20:30:32 +00:00
Forgejo actions[bot]
2b42fbabfc Deploy 2025-02-09 2025-02-09 20:58:28 +00:00
Forgejo actions[bot]
f40ecfb846 Deploy 2025-02-09 2025-02-09 07:51:17 +00:00
Forgejo actions[bot]
c98da1d761 Deploy 2025-02-07 2025-02-07 07:47:35 +00:00
Forgejo actions[bot]
dc6ebad029 Deploy 2025-02-06 2025-02-06 20:09:43 +00:00
Forgejo actions[bot]
9b9df8f49a Deploy 2025-02-05 2025-02-05 18:41:44 +00:00
Forgejo actions[bot]
603d0d3b99 Deploy 2025-02-03 2025-02-03 20:18:05 +00:00
Forgejo actions[bot]
c1f32223e9 Deploy 2025-02-03 2025-02-03 08:05:25 +00:00
Forgejo actions[bot]
012b7386c7 Deploy 2025-02-03 2025-02-03 07:50:34 +00:00
46 changed files with 497 additions and 6264 deletions

View file

@ -1,61 +0,0 @@
name: Build
on:
push:
branches:
- main
jobs:
deploy:
runs-on: docker
permissions:
contents: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
with:
run_install: |
- recursive: true
args: [--frozen-lockfile, --strict-peer-dependencies]
- name: Build
run: |
pnpm build --dest DIST
rm -rf .pnpm-store
- name: Commit build
run: |
current_version=v$(cat package.json | grep version | grep -o -E '([0-9]+\.){2}[0-9]+')
git switch build
previous_version=$(git describe --tags --abbrev=0 2>/dev/null || echo '')
tag_message=`git log --pretty='format:%s' $previous_version..`
shopt -s extglob
shopt -s dotglob
rm -rf !(DIST|.git|.|..)
mv DIST/* .
rm -rf DIST
git add -A
git config --local user.email "forgejo-actions[bot]@noreply.pleshevski.ru"
git config --local user.name "Forgejo actions[bot]"
git commit -m "Deploy $(date +%Y-%m-%d)" --allow-empty
if [[ "$current_version" != "$previous_version" ]]; then
git tag $current_version -m "$current_version
$tag_message"
fi
- name: Push changes
uses: ad-m/github-push-action@d91a481090679876dfc4178fef17f286781251df # v0.8.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: build
tags: true

View file

@ -1,16 +0,0 @@
on:
push:
branches:
- 'renovate/*'
jobs:
test-dependencies:
runs-on: docker
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
with:
run_install: |
- recursive: true
args: [--frozen-lockfile, --strict-peer-dependencies]
- run: pnpm build

19
.gitignore vendored
View file

@ -1,19 +0,0 @@
# editors
.idea/
.vscode/
*.swp
# direnv
.direnv
.envrc
# nodejs
node_modules/
# nix
/result
# custom
.DS_Store
# vuepress
/docs/.vuepress/.cache
/docs/.vuepress/.temp
/docs/.vuepress/dist
/dist

43
404.html Normal file
View file

@ -0,0 +1,43 @@
<!doctype html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="generator" content="VuePress 2.0.0-rc.20" />
<style>
:root {
--vp-c-bg: #fff;
}
[data-theme='dark'] {
--vp-c-bg: #1b1b1f;
}
html,
body {
background-color: var(--vp-c-bg);
}
</style>
<script>
const useChoice = localStorage.getItem('vuepress-color-scheme')
const systemStatus =
'matchMedia' in window
? window.matchMedia('(prefers-color-scheme: dark)').matches
: false
if (useChoice === 'light') {
document.documentElement.dataset.theme = 'light'
} else if (useChoice === 'dark' || systemStatus) {
document.documentElement.dataset.theme = 'dark'
}
</script>
<meta property="og:url" content="https://pleshevski.ru/404.html"><meta property="og:site_name" content="Дмитрий Плешевский"><meta property="og:type" content="website"><meta property="og:locale" content="ru-RU"><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":""}</script><title>Дмитрий Плешевский</title><meta name="description" content=" ">
<link rel="preload" href="/assets/style-B-bsq3_-.css" as="style"><link rel="stylesheet" href="/assets/style-B-bsq3_-.css">
<link rel="modulepreload" href="/assets/app-B7m8SWwm.js"><link rel="modulepreload" href="/assets/404.html-B6yqFRPF.js">
<link rel="prefetch" href="/assets/index.html-BRLRz9jS.js" as="script"><link rel="prefetch" href="/assets/works.html-DpBd8aaJ.js" as="script"><link rel="prefetch" href="/assets/index.html-BnpG60Ho.js" as="script"><link rel="prefetch" href="/assets/works.html-BcdtPw7E.js" as="script">
</head>
<body>
<div id="app"><!--[--><div class="vp-theme-container" vp-container data-v-4a26b356><main class="page" data-v-4a26b356><div vp-content data-v-4a26b356><h1 data-v-4a26b356>404</h1><blockquote data-v-4a26b356>Искали кота?</blockquote><a class="route-link" href="/" data-v-4a26b356>Вернуться на главную</a></div></main></div><!--[--><!----><!--]--><!--]--></div>
<script type="module" src="/assets/app-B7m8SWwm.js" defer></script>
</body>
</html>

View file

@ -1,24 +0,0 @@
PREFIX ?= dist
.PHONY: help
help:
cat Makefile
.PHONY: build
build:
pnpm run build --dest $(PREFIX)
.PHONY: install
install: build
.PHONY: dev
dev:
pnpm run dev
.PHONY: deps
deps:
pnpm install
.PHONY: init-git-hooks
init-git-hooks:
ln -sf $(PWD)/scripts/pre-commit $(PWD)/.git/hooks/pre-commit

View file

@ -0,0 +1 @@
import{_ as e,c as o,a,o as n}from"./app-B7m8SWwm.js";const r={};function l(p,t){return n(),o("div",null,t[0]||(t[0]=[a("p",null,"404 Not Found",-1)]))}const c=e(r,[["render",l],["__file","404.html.vue"]]),m=JSON.parse('{"path":"/404.html","title":"","lang":"ru-RU","frontmatter":{"layout":"NotFound","head":[["meta",{"property":"og:url","content":"https://pleshevski.ru/404.html"}],["meta",{"property":"og:site_name","content":"Дмитрий Плешевский"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"ru-RU"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\"}"]]},"headers":[],"git":{},"filePathRelative":null}');export{c as comp,m as data};

31
assets/app-B7m8SWwm.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +0,0 @@
import { defineClientConfig } from "vuepress/client";
import WorksPage from "./pages/WorksPage.vue";
export default defineClientConfig({
layouts: { WorksPage },
});

View file

@ -1,98 +0,0 @@
import { defineUserConfig } from "vuepress";
import { viteBundler } from "@vuepress/bundler-vite";
import { mkMyTheme } from "./theme.js";
import { redirectPlugin } from "@vuepress/plugin-redirect";
export default defineUserConfig({
lang: "ru-RU",
title: "Дмитрий Плешевский",
description: " ",
locales: {
"/": {
lang: "ru-RU",
title: "Дмитрий Плешевский",
},
"/eng/": {
lang: "en-US",
title: "Dmitriy Pleshevskiy",
},
},
theme: mkMyTheme({
hostname: "https://pleshevski.ru",
repo: "https://git.pleshevski.ru/pleshevskiy/pleshevski.ru",
locales: {
"/": {
selectLanguageName: "Русский",
navbar: ["/", "/works"],
notFound: [
"Верните страницу!",
"Мы потеряли страницу...",
"Вы заблокированы в лабиринте.",
"Искали кота?",
"Страница украдена.",
"Ошиблись в параллельной вселенной.",
],
backToHome: "Вернуться на главную",
worksTable: {
name: "Название",
description: "Описание",
role: "Роль",
technologies: "Технологии",
status: "Статус",
dates: "Даты",
},
},
"/eng/": {
selectLanguageName: "English",
navbar: ["/eng/", "/eng/works"],
notFound: [
"Return the page!",
"We lost a page...",
"You're blocked in a labyrinth.",
"Looking for a cat?",
"The page has been stolen.",
"Wrong turn in parallel universe.",
],
backToHome: "Back to home",
worksTable: {
name: "Name",
description: "Description",
role: "Role",
technologies: "Technologies",
status: "Status",
dates: "Dates",
},
},
},
themePlugins: {
seo: {
autoDescription: false,
isArticle: () => false,
},
linksCheck: {
build: "error",
},
mediumZoom: false,
sitemap: {
changefreq: "monthly",
},
},
}),
plugins: [
redirectPlugin({
config: {
"/rus/": "/",
"/rus/works.html": "/works.html",
},
}),
],
bundler: viteBundler(),
});

View file

@ -1,9 +0,0 @@
export type NonEmptyArray<T> = [T, ...T[]];
export function renderDate(date: Date): string {
return date.toLocaleDateString(undefined, {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
}

View file

@ -1,73 +0,0 @@
<script lang="ts">
function date2num(date: Date | undefined): number {
return date?.valueOf() ?? Infinity;
}
export default {
name: "WorksPage",
computed: {
tableTheme() {
return this.$themeLocale.worksTable ?? {};
},
},
};
</script>
<script lang="ts" setup>
import { CHRONOLOGICAL_WORKS } from "../data.ts";
import { renderDate } from "../../../global.ts";
import { work as w } from "../domain";
import { computed } from "vue";
const works = computed(() =>
CHRONOLOGICAL_WORKS.concat().sort(
(a, b) =>
date2num(b.endDate) - date2num(a.endDate) ||
date2num(b.startDate) - date2num(a.startDate),
),
);
</script>
<template>
<table>
<thead>
<tr>
<th>{{ tableTheme.name }}</th>
<th>{{ tableTheme.description }}</th>
<th>{{ tableTheme.role }}</th>
<th>{{ tableTheme.technologies }}</th>
<th>{{ tableTheme.status }}</th>
<th>{{ tableTheme.dates }}</th>
</tr>
</thead>
<tbody>
<tr v-for="work in works">
<td>
<a rel="nofollow noopener" :href="w.getExternalLink(work)">
{{ work.name }}
</a>
</td>
<td>{{ work.description }}</td>
<td v-html="work.roles.join(', ')"></td>
<td>{{ work.technologies.join(", ") }}</td>
<td>{{ work.status }}</td>
<td>
<div>
<small :class="{ grey: work.endDate }">
{{ renderDate(work.startDate) }}
</small>
</div>
<div v-if="work.endDate">
<small>{{ renderDate(work.endDate) }}</small>
</div>
</td>
</tr>
</tbody>
</table>
</template>
<style lang="css">
.grey {
color: rgba(0, 0, 0, 0.4);
}
</style>

View file

@ -1 +0,0 @@
export { default as ChronologicalWorksTable } from "./ChronologicalWorksTable.vue";

View file

@ -1,375 +0,0 @@
import { Role } from "./domain/Role.ts";
import { Status } from "./domain/Status.ts";
import { Technology } from "./domain/Technology.ts";
import type { Work } from "./domain/Work.ts";
export const CHRONOLOGICAL_WORKS: Work[] = [
{
name: "nixeovim",
url: "/pleshevskiy/nixeovim",
description: "Configure and build neovim editor using nix",
roles: [Role.Author],
technologies: [Technology.Nix],
startDate: new Date("2024-04-24"),
status: Status.ActiveDeveloped,
},
{
name: "picsg",
url: "/pleshevskiy/picsg",
description:
"A tool for steganographing information in a picture encoded using the Vernam cipher.",
roles: [Role.Author],
technologies: [Technology.Haskell],
startDate: new Date("2024-04-13"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "Mindustry tools",
url: "/pleshevskiy/mindustry-tools",
description: "Tools for the Mindustry game",
roles: [Role.Author],
technologies: [Technology.Nix, Technology.Godot],
startDate: new Date("2024-01-07"),
status: Status.PassivelyMaintained,
},
{
name: "Master Progress Rosmintrud tools",
url: "https://rosmintrud.masterprogress.ru",
description:
"Internal service to prepare documents for the rosmintrud (SPA)",
roles: [Role.TechLead],
technologies: [
Technology.Deno,
Technology.Sqlite,
Technology.TypeScript,
Technology.Vue,
Technology.Docker,
Technology.Woodpecker,
Technology.Nix,
],
startDate: new Date("2023-07-03"),
status: Status.PassivelyMaintained,
},
{
name: "yandexgpt_tg_bot",
url: "/pleshevskiy/yandexgpt_tg_bot",
description: "The Telegram bot to describe article with link by YandexGPT.",
roles: [Role.Author],
technologies: [Technology.JavaScript, Technology.NodeJS, Technology.Nix],
startDate: new Date("2023-06-27"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "tree-sitter-plpgsql",
url: "/pleshevskiy/tree-sitter-plpgsql",
description: "plpgsql grammar for tree-sitter",
roles: [Role.Author],
technologies: [
Technology.C,
Technology.JavaScript,
Technology.TreeSitter,
Technology.Nix,
],
startDate: new Date("2023-01-05"),
status: Status.PassivelyMaintained,
},
{
name: "wd2",
url: "/pleshevskiy/wd2",
description:
"A wrapper over d2 which allows to use additional configs from d2 file",
roles: [Role.Author],
technologies: [Technology.Bash, Technology.Nix],
startDate: new Date("2022-12-12"),
endDate: new Date("2023-07-31"),
status: Status.AsIs,
},
{
name: "tree-sitter-d2",
url: "/pleshevskiy/tree-sitter-d2",
description: "d2 grammar for tree-sitter",
roles: [Role.Author],
technologies: [
Technology.C,
Technology.JavaScript,
Technology.TreeSitter,
Technology.Nix,
],
startDate: new Date("2022-12-04"),
status: Status.ActiveDeveloped,
},
{
name: "nix2lua",
url: "/mynix/nix2lua",
description:
"This is a small but functional library that converts your nix configurations into lua format.",
roles: [Role.Author],
technologies: [Technology.Nix, Technology.Lua],
startDate: new Date("2022-11-22"),
status: Status.PassivelyMaintained,
},
{
name: "vnetod",
url: "/pleshevskiy/vnetod",
description: "Dotenv section switcher",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-29"),
status: Status.PassivelyMaintained,
},
{
name: "estring",
url: "/pleshevskiy/estring",
description: "A simple way to parse a string using type annotations.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-23"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "enve",
url: "/pleshevskiy/enve",
description:
"It helps you work with environment variables and convert it to any type using only type annotations",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-18"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "docker stack drone plugin",
url: "/pleshevskiy/docker_stack",
description: "Deploy to production using `docker stack deploy`",
roles: [Role.Author],
technologies: [Technology.Docker, Technology.Drone, Technology.Woodpecker],
startDate: new Date("2022-06-06"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "dexios",
url: "/github/dexios",
description:
"Dexios is a fast, secure, and open source command-line encryption tool.",
roles: [Role.Collaborator],
technologies: [Technology.Rust],
startDate: new Date("2022-06-01"),
endDate: new Date("2023-02-28"),
},
{
name: "recipes",
url: "/pleshevskiy/recipes",
description: "Site with recipes which cares about privacy",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.Deno, Technology.Rust],
startDate: new Date("2022-05-04"),
status: Status.PassivelyMaintained,
},
{
name: "pleshevski.ru",
url: "/pleshevskiy/pleshevski.ru",
description: "Source code of my personal site",
roles: [Role.Author],
technologies: [
Technology.TypeScript,
Technology.Vue,
Technology.Vuepress,
Technology.Nix,
],
startDate: new Date("2022-03-16"),
status: Status.PassivelyMaintained,
},
{
name: "paren",
url: "/pleshevskiy/paren",
description: "Library for parsing and rendering information.",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.Deno],
startDate: new Date("2022-03-14"),
endDate: new Date("2024-07-25"),
status: Status.Experimental,
},
{
name: "hwt",
url: "/pleshevskiy/hwt",
description:
"healthy workaholic timer A tool that keeps you from breaking your health by working all day.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-02-04"),
endDate: new Date("2024-07-25"),
status: Status.AsIs,
},
{
name: "ood_persistence",
url: "/pleshevskiy/ood_persistence",
description:
"Asynchronous and synchronous interfaces and persistence implementations for your OOD architecture ",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2021-10-12"),
endDate: new Date("2021-10-21"),
status: Status.Deprecated,
},
{
name: "migra",
url: "/pleshevskiy/migra",
description: "Simple SQL migration manager for your project.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2021-01-31"),
endDate: new Date("2022-03-17"),
status: Status.AsIs,
},
{
name: "espruino-starter",
url: "/pleshevskiy/espruino-starter",
description:
"Quickly start creating your new project on the espruino board or a board based on it.",
roles: [Role.Author],
technologies: [Technology.JavaScript],
startDate: new Date("2021-08-23"),
status: Status.AsIs,
},
{
name: "react-rest-request",
url: "/pleshevskiy/react-rest-request",
description: "Minimalistic REST API client for React inspired by Apollo.",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.React],
startDate: new Date("2020-10-04"),
endDate: new Date("2023-03-02"),
status: Status.Deprecated,
},
{
name: "sonic-channel",
url: "/pleshevskiy/sonic-channel",
description: "Rust client for sonic search backend.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2020-07-18"),
status: Status.PassivelyMaintained,
},
{
name: "itconfig",
url: "/pleshevskiy/itconfig",
description:
"Easy build a configs from environment variables and use it in globally.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2019-12-22"),
endDate: new Date("2022-07-24"),
status: Status.Deprecated,
},
{
name: "it-fsm",
url: "/pleshevskiy/it-fsm",
description: "Simple full-featured finite state machine for your project",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.NodeJS, Technology.Deno],
startDate: new Date("2019-10-11"),
status: Status.PassivelyMaintained,
},
{
name: "Cabinet Master Progress",
url: "https://cabinet.masterprogress.ru",
description:
"Student's cabinet of the educational center Master Progress (SSR + SPA)",
roles: [Role.TechLead],
technologies: [
Technology.Python,
Technology.Flask,
Technology.Postgresql,
Technology.TypeScript,
Technology.React,
Technology.Docker,
Technology.Woodpecker,
Technology.Nix,
],
startDate: new Date("2019-09-22"),
status: Status.PassivelyMaintained,
},
{
name: "genrss",
url: "/pleshevskiy/genrss",
description: "RSS generator for python",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2019-07-23"),
status: Status.AsIs,
},
{
name: "marshmallow_pageinfo",
url: "/pleshevskiy/marshmallow_pageinfo",
description: "Page info marshmallow schema for api",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2019-10-05"),
endDate: new Date("2023-03-02"),
status: Status.AsIs,
},
{
name: "Binary Management",
url: "https://www.binarymanagement.com",
description: "Project management tool for interior designers",
roles: [Role.Developer, Role.TechLead, Role.TeamLead],
technologies: [
Technology.TypeScript,
Technology.NodeJS,
Technology.React,
Technology.Antd,
Technology.Docker,
Technology.Drone,
Technology.Rust,
Technology.Nix,
],
startDate: new Date("2018-09-15"),
status: Status.ActiveDeveloped,
},
{
name: "Core Spirit",
url: "https://corespirit.com",
description: "Social platform focusing on human and planetary enhancement",
roles: [Role.Developer],
technologies: [
Technology.TypeScript,
Technology.NodeJS,
Technology.Go,
Technology.Python,
Technology.React,
Technology.Docker,
Technology.Drone,
],
startDate: new Date("2018-09-05"),
endDate: new Date("2019-12-31"),
},
{
name: "Master Progress",
url: "https://masterprogress.ru",
description:
"Main website of the educational center Master Progress (SSR + Forms)",
roles: [Role.TechLead],
technologies: [
Technology.Python,
Technology.Flask,
Technology.JavaScript,
Technology.Nix,
],
startDate: new Date("2018-04-10"),
status: Status.PassivelyMaintained,
},
{
name: "ictmpl",
url: "/pleshevskiy/ictmpl",
description: "Generate projects from templates",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2018-06-30"),
endDate: new Date("2023-03-02"),
status: Status.AsIs,
},
];

View file

@ -1,7 +0,0 @@
export enum Role {
Collaborator = "collaborator",
Author = "author",
TechLead = "tech&nbsp;lead",
TeamLead = "team&nbsp;lead",
Developer = "developer",
}

View file

@ -1,25 +0,0 @@
export enum Status {
// New features are being added and bugs are being fixed.
ActiveDeveloped = "actively-developed",
// There are no plans for new features, but the maintainer intends to respond
// to issues that get filed.
PassivelyMaintained = "passively-maintained",
// The package is feature complete, the maintainer does not intend to continue
// working on it or providing support, but it works for the purposes it was
// designed for.
AsIs = "as-is",
// The author wants to share it with the community but is not intending to
// meet anyone's particular use case.
Experimental = "experimental",
// The current maintainer would like to transfer the package to someone else.
LookingForMaintainer = "looking-for-maintainer",
// The maintainer does not recommend using this package (the description of the
// package can describe why, there could be a better solution available or
// there could be problems with the package that the author does not want to fix).
Deprecated = "deprecated",
}

View file

@ -1,27 +0,0 @@
export enum Technology {
C = "C",
Go = "Go",
JavaScript = "JS",
TypeScript = "TS",
Rust = "Rust",
Python = "Python",
Php = "PHP",
Deno = "Deno",
NodeJS = "NodeJS",
Flask = "Flask",
React = "React",
Antd = "Antd",
Postgresql = "PostgreSQL",
Docker = "Docker",
Drone = "Drone CI",
Woodpecker = "Woodpecker CI",
Bash = "Bash",
TreeSitter = "TreeSitter",
Nix = "Nix",
Lua = "Lua",
Sqlite = "Sqlite",
Vue = "Vue",
Vuepress = "Vuepress",
Godot = "Godot",
Haskell = "Haskell",
}

View file

@ -1,20 +0,0 @@
import type { NonEmptyArray } from "../../../global.ts";
import { Role } from "./Role.ts";
import { Status } from "./Status.ts";
import { Technology } from "./Technology.ts";
export interface Work {
name: string;
url: string;
description: string;
roles: NonEmptyArray<Role>;
technologies: NonEmptyArray<Technology>;
startDate: Date;
endDate?: Date;
status?: Status;
}
export const getExternalLink: (work: Pick<Work, "url">) => string = (work) =>
work.url.startsWith("https://")
? work.url
: new URL(work.url, "https://git.pleshevski.ru").toString();

View file

@ -1,5 +0,0 @@
export { Role } from "./Role.ts";
export { Status } from "./Status.ts";
export { Technology } from "./Technology.ts";
export type { Work } from "./Work.ts";
export * as work from "./Work.ts";

View file

@ -1 +0,0 @@
export * from "./ChronologicalWorksTable";

View file

@ -1,42 +0,0 @@
<script setup>
// See: https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/theme-default/layouts/Layout.vue
import ParentLayout from '@vuepress/theme-default/layouts/Layout.vue'
import { ChronologicalWorksTable } from "../modules/work";
</script>
<template>
<ParentLayout>
<template #page-bottom>
<div class="works-table-wrapper">
<ChronologicalWorksTable />
</div>
</template>
</ParentLayout>
</template>
<style lang="css" scoped>
.works-table-wrapper {
margin: 0 auto;
padding: 0 2rem;
max-width: 1224px;
box-sizing: border-box
}
.works-table-wrapper :deep(table) {
width: 100%;
}
</style>
<style lang="css">
:root {
--content-width: 960px;
}
.vp-page .theme-default-content {
padding-bottom: 0 !important;
}
.vp-page-meta {
display: none;
}
</style>

View file

@ -1,10 +0,0 @@
import { DefaultThemeOptions, defaultTheme } from "@vuepress/theme-default";
export const mkMyTheme = (options: DefaultThemeOptions) => {
// returns a theme object
return {
name: "my-theme",
extends: defaultTheme(options),
};
};

View file

@ -1,122 +0,0 @@
---
home: true
title: Resume
heroText: null
---
Always up-to-date link to [resume](/eng/).
## Overview
My name is Dmitriy Pleshevskiy.
As an open-source development enthusiast, I am always ready to collaborate and
participate in exciting projects. I am inspired by the opportunity to contribute
to the community and share knowledge. The core technologies I work with include
`TypeScript`, `Rust`, `Python`, `PostgreSQL`, `Minio`, `RabbitMQ`, `React`,
`VueJS`, and `Docker`. I have a particular passion for functional programming,
which enables writing clean and efficient code. As a NixOS evangelist, I not
only actively use it in my projects but also promote its adoption among
individuals and companies, highlighting its advantages and assisting in its
implementation within their infrastructure. My extensive experience in backend
and frontend development, as well as in DevOps, allows me to tackle complex
challenges effectively. Additionally, I have expertise as an architect, team
leader, and mentor.
## Skills
#### Programming Languages:
- TypeScript (prefer, solid 9-year exp)
- SQL (prefer, solid 8-year exp)
- Rust (prefer, solid 5-year exp)
- Python (solid 9-year exp)
- Haskell
- Bash (8-year exp)
- Java
- C#
- C++
#### Repositories:
- PostgreSQL (prefer, solid 8-year exp)
- MySQL
- Sqlite
- MsSQL
- MongoDB
- Redis
- Minio (prefer, solid 5-year exp)
---
I also have extensive experience in creating the following applications:
- Traditional (SSR + Forms)
- API (REST/GraphQL/WebSocket/EventSource)
- Dynamic (SPA)
- Hybrid (SSR + SPA)
- Console
- Cross-platform
## Stack
#### Backend (Rust)
- `axum` (prefer, solid 2-year exp)
- `async-graphql` (prefer, solid 2-year exp)
- `shaku` (prefer, solid 2-year exp)
- `bb8` + `postgres-types` (prefer, solid 5-year exp)
- `diesel` (2-year exp)
#### Backend (Node.JS)
- `Apollo` (solid 5-year exp)
- `Express` (solid 9-year exp)
- `Nest.JS`
- `Knex.js` / `Objection.js` (solid 5-year exp)
- `Sequelize`
#### Frontend
- `React` (solid 8-year exp)
- `VueJS` (prefer, solid 3-year exp)
- `Cypress` (prefer, solid 3-year exp)
- `JQuery`
- `Antd` / `Antdv`
- `PostCSS` (prefer, solid 5-year exp)
- `Sass` (prefer, solid 8-year exp)
- `Less` (weak 4-year exp)
#### DevOps
- `NixOS` / `NixOps` / `Nix dev shell` (prefer, solid 3-year exp)
- `Docker Swarm` (solid 6-year exp)
- `Kubernetes` (weak 5-year exp)
- `Woodpecker CI` (prefer, solid 4-year exp)
- `Drone CI` (solid 3-year exp)
- `Gitlab CI` (solid 7-year exp)
- `GitHub Actions` (4-year exp)
## Interests
Open-source projects are my passion! I develop, maintain and improve projects in
my spare time.
Besides programming, I love to cook and spend time with my beloved family!
## Contacts
Simplex (Prefer): [Dmitriy
Pleshevskiy](https://simplex.chat/contact#/?v=2-7&smp=smp%3A%2F%2FZKe4uxF4Z_aLJJOEsC-Y6hSkXgQS5-oc442JQGkyP8M%3D%40smp17.simplex.im%2F8JE7lkP68DZG-1DP8U8_njTlIz9fzRzf%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAxdWiN9so1FqPVTsKhS4Y2OK80zzUvsIZ1Yo77kYV6Co%253D%26srv%3Dogtwfxyi3h2h5weftjjpjmxclhb5ugufa5rcyrmg7j4xlch7qsr5nuqd.onion)
Telegram: [Dmitriy Pleshevskiy](https://telegram.me/da_pranaya)
Matrix: `@pleshevskiy:matrix.org`
Email: `dmitriy[at]pleshevski[dot]ru`
## Links
- [Forgejo](https://git.pleshevski.ru/)
- [Github (Suspended)](https://github.com/pleshevskiy)

View file

@ -1,121 +0,0 @@
---
title: Works
layout: WorksPage
sidebar: false
---
## Highlighted working experience
### Binary Management
- Dates: August 2018 currently
- Roles: Lead Fullstack Developer, Team Lead, Architect
Development of a Project Management Tool for Interior Designers
##### Backend GraphQL API
Stack: `Node.JS`, `Apollo`, `PostgreSQL`, `Redis`, `BullMQ`
- Migrated database triggers into business logic. Code became easier to read and
maintain, and the system became more reliable.
- Introduced unit testing and integration testing practices. I wrote over 70% of
all tests myself.
- Added GraphQL subscriptions for dynamic updates.
##### Frontend
Stack: `React`, `Apollo`, `Antd`
- Formed a UIKit and general components, optimized complex and loaded
components.
- Changed API work on the frontend.
- Introduced integration testing practice using Cypress.
- Migrated the entire project to TypeScript. Created isolated system modules.
##### Leadership of the Team
- Introduced TDD (Test-Driven Development) practices.
- Brought the "Critical Chain Method", the "Buffer Method", and the "Backward
Planning" method into the project. Helped the team get in sync,
releasing small batches every week.
- Created individual development plans for team members.
##### Architecture
- Broke down the entire codebase into modules by feature.
- Optimized `PostgreSQL` database, splitting company data into separate schemas
and applying partitioning tables.
- Added query caching with Redis.
- Reduced infrastructure costs by 5 times, migrating the project from Kubernetes
to NixOS.
---
### Core Spirit (Back Office)
- Даты: Август 2024 - currently
- Роль: Lead Fullstack Developer
Development of the Back Office for Core Spirit social platform.
- Integrated `Dependabot`, which helped update all outdated
dependencies. Replaced webpack with `vite`.
---
### Master Progress
- Dates: May 2018 - currently (Passively maintained)
- Role: Tech Lead
Development web infrastructure of the educational center Master Progress
- [The main site](https://masterprogress.ru) (`Python`, `Flask`).
- [Student's cabinet](https://cabinet.masterprogress.ru) (`Python`,
`Flask`, `TypeScript`, `React`, `PostgreSQL`).
- [A tool for rosmintrud](https://rosmintrud.masterprogress.ru)
(`Deno`, `Vue`, `Typescript`)
- A complete infrastructure was created on `NixOS`. Before that, I had created
an infrastructure using `Drone CI` / `Woodpecker CI` and `Docker
swarm`, which has been running for over 5 years.
---
### Core Spirit
- Dates: August 2018 - May 2020, August 2024 - currently
- Role: Lead Fullstack Developer
Development of Social platform focusing on human and planetary enhancement.
- A REST API (using `Node.JS`, `Express`, and `PostgreSQL`) for the main website
and back office. I also got to work with a new version of the REST
API using `Go` and `PostgreSQL`.
- Auto poster to various social networks and messengers
(Facebook, LinkedIn, Twitter, Telegram).
- Neural network for automatic categorization of articles.
---
#### MERLION
- Dates: March 2016 May 2018
- Role: Senior Fullstack developer
In this company there were 6 considerable projects I have successfully
completed:
- optimize the creation of promotional pages (PHP, JavaScript)
- support main traditional site <https://citilink.ru> (PHP, JavaScript)
- development of parsing to monitor products for changes in price,
quantity/availability in stock, rating and other fields based on data from 55
websites (Node.JS, Express)
- work with neural networks for matching of goods
- development face recognition apps for Android (Java)
---
## Chronology
Public projects only.

View file

@ -1,121 +0,0 @@
---
home: true
title: Резюме
heroText: null
---
Всегда актуальная ссылка на [резюме](/).
## Общие сведения
Меня зовут Дмитрий Плешевский.
Как энтузиаст open-source разработки, я всегда готов к сотрудничеству и участию
в интересных проектах. Меня вдохновляет возможность вносить вклад в сообщество и
делиться знаниями. Основные технологии, с которыми я работаю, включают
`TypeScript`, `Rust`, `Python`, `PostgreSQL`, `Minio`, `RabbitMQ`, `React`,
`VueJS`, `Docker`. Особенно люблю функциональное программирование, которое
позволяет писать чистый и эффективный код. Как евангелист `NixOS`, я не только
активно использую его в своих проектах, но и активно агитирую людей и компании
переходить на эту систему, подчеркивая ее преимущества и помогая внедрять ее в
их инфраструктуру. Большой опыт в разработке backend и frontend приложений, а
также в DevOps, позволяет эффективно решать сложные задачи. Также имею опыт
работы в качестве архитектора, руководителя команды и наставника.
## Умения
#### Языки программирования:
- TypeScript (предпочитаю, твёрдый 9-летний опыт)
- SQL (предпочитаю, твёрдый 8-летний опыт)
- Rust (предпочитаю, 5-летний опыт)
- Python (твёрдый 9-летний опыт)
- Haskell
- Bash (8-летний опыт)
- Java
- C#
- C++
#### Хранилища данных:
- PostgreSQL (предпочитаю, твёрдый 8-летний опыт)
- MySQL
- Sqlite
- MsSQL
- MongoDB
- Redis
- Minio (предпочитаю, твердый 5-летний опыт)
---
Я так же имею большой опыт в создании следующих типов приложений:
- Традиционные (SSR + Forms)
- API (REST/GraphQL/WebSocket/EventSource)
- Динамическое (SPA)
- Гибридное (SSR + SPA)
- Консольные
- Кроссплатформенные
## Stack
#### Backend (Rust)
- `axum` (предпочитаю, твёрдый 2-летний опыт)
- `async-graphql` (предпочитаю, твёрдый 2-летний опыт)
- `shaku` (предпочитаю, твёрдый 2-летний опыт)
- `bb8` + `postgres-types` (предпочитаю, твёрдый 5-летний опыт)
- `diesel` (2-летний опыт)
#### Backend (Node.JS)
- `Apollo` (твёрдый 5-летний опыт)
- `Express` (твёрдый 9-летний опыт)
- `Nest.JS`
- `Knex.js` / `Objection.js` (твёрдый 5-летний опыт)
- `Sequelize`
#### Frontend
- `React` (твёрдый 8-летний опыт)
- `VueJS` (предпочитаю, твёрдый 4-летний опыт)
- `Cypress` (предпочитаю, твёрдый 3-летний опыт)
- `JQuery`
- `Antd` / `Antdv`
- `PostCSS` (предпочитаю, твёрдый 5-летний опыт)
- `Sass` (предпочитаю, твёрдый 8-летний опыт)
- `Less` (слабый 4-летний опыт)
#### DevOps
- `NixOS` / `NixOps` / `Nix dev shell` (предпочитаю, твёрдый 3-летний опыт)
- `Docker Swarm` (твёрдый 6-летний опыт)
- `Kubernetes` (слабый 5-летний опыт)
- `Woodpecker CI` (твёрдый 4-летний опыт)
- `Drone CI` (твёрдый 3-летний опыт)
- `Gitlab CI` (твёрдый 7-летний опыт)
- `GitHub Actions` (4-летний опыт)
## Интересы
Open-source проекты - моя страсть! Разрабатываю, поддерживаю и улучшаю проекты в
своё свободное время.
Помимо программирования я люблю готовить и проводить время со своей любимой
семьей!
## Контакты
Simplex (Предпочтительно): [Dmitriy
Pleshevskiy](https://simplex.chat/contact#/?v=2-7&smp=smp%3A%2F%2FZKe4uxF4Z_aLJJOEsC-Y6hSkXgQS5-oc442JQGkyP8M%3D%40smp17.simplex.im%2F8JE7lkP68DZG-1DP8U8_njTlIz9fzRzf%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAxdWiN9so1FqPVTsKhS4Y2OK80zzUvsIZ1Yo77kYV6Co%253D%26srv%3Dogtwfxyi3h2h5weftjjpjmxclhb5ugufa5rcyrmg7j4xlch7qsr5nuqd.onion)
Telegram: [Dmitriy Pleshevskiy](https://telegram.me/da_pranaya)
Matrix: `@pleshevskiy:matrix.org`
Email: `dmitriy[at]pleshevski[dot]ru`
## Ссылки
- [Forgejo](https://git.pleshevski.ru/)
- [Github (Приостановлен)](https://github.com/pleshevskiy)

View file

@ -1,122 +0,0 @@
---
title: Работы
layout: WorksPage
sidebar: false
---
## Выделенный опыт работы
### Binary Management
- Даты: Август 2018 по настоящее время
- Роли: Lead Fullstack Developer, Team Lead, Architect
Разработка инструмента управления проектами для дизайнеров интерьера.
##### Backend GraphQL API
Стек: `Node.JS`, `Apollo`, `PostgreSQL`, `Redis`, `BullMQ`
- Перенес триггеры базы данных в бизнес-логику. Проще стало читать код, вносить
изменение и система стала надежнее.
- Ввёл практику написания unit тестов и интеграционных тестов. Самолично написал
более 70% всех тестов.
- Добавил GraphQL подписки для динамичного обновления.
##### Frontend
Стек: `React`, `Apollo`, `Antd`
- Сформировал UIKit и общие компоненты, оптимизировал сложные и нагруженные
компоненты.
- Изменил работу с API на фронтенде.
- Внедрил практику написания интеграционных тестов с помощью cypress.
- Полностью перенес проект на TypeScript. Сформировал изолированные модули
системы.
##### Руководство командой
- Ввёл практику TDD (Test-Driven Development).
- Я привнес в проект "метод критической цепи", "метод буфера" и "метод
планирования с конца". Помог команде войти в ритм, чтобы выпускать релизы каждую
неделю небольшими партиями.
- Составлял индивидуальный план развития для членов команды.
##### Архитектура
- Разбил всю кодовую базу на модули по фичам.
- Ускорил базу данных `PostgreSQL`, разбив данные компаний по отдельным схемам и
применив партиципирование таблиц.
- Добавил кеширование запросов с `Redis`.
- Уменьшил затраты на инфраструткуру в 5 раз, перенес весь проект с kubernetes
на `NixOS`.
---
### Core Spirit (Back Office)
- Даты: Август 2024 - по настоящее время
- Роль: Lead Fullstack Developer
Разработка бэк-офиса для социальной платформы Core Spirit.
- Интегрировал Dependabot, который помог обновить все устаревшие
зависимости. Заменил webpack на vite.
---
### Master Progress
- Даты: Май 2018 - по настоящее время (Пассивная поддержка)
- Роль: Tech Lead
Разработка веб-инфраструктуры образовательного центра Мастер Прогресс.
- [Главного сайта](https://masterprogress.ru) (`Python`, `Flask`).
- [Кабинета студента](https://cabinet.masterprogress.ru) (`Python`, `Flask`,
`TypeScript`, `React`, `PostgreSQL`).
- [Инструмента для работы с rosmintrud](https://rosmintrud.masterprogress.ru)
(`Deno`, `Vue`, `Typescript`)
- Создана полная инфраструктура на `NixOS`. До этого создал инфраструктуру
используя `Drone CI` / `Woodpecker CI` и `Docker swarm`, которая проработала
более 5 лет.
---
### Core Spirit
- Даты: Август 2018 - May 2020, Август 2024 - по настоящее время
- Роль: Lead Fullstack Developer
Разработка социальной платформы, сфокусированной на улучшении человека и
планеты.
- REST API (`Node.JS`, `Express`, `PostgreSQL`) для основного сайта и
бэк-офиса. Успел поработать с новой версией REST API на `Go`, `PostgreSQL`
- Автопостер в различные социальные сети и мессенджеры (Facebook,
LinkedIn, Twitter, Telegram).
- Создал нейронную сеть для автоматической категоризации статей.
---
### MERLION
- Dates: March 2016 May 2018
- Role: Senior Fullstack developer
В этой компании было 6 значительных проектов, которые я успешно завершил:
- Оптимизация создания рекламных страниц (PHP, JavaScript)
- Поддержка основного традиционного сайта <https://citilink.ru> (PHP,
JavaScript)
- Разработка парсинга для мониторинга товаров на предмет изменения цены,
количества/наличия на складе, рейтинга и других полей на основе данных с 55+
сайтов (Node.js, Express)
- Работа с нейронными сетями для подбора товаров
- Разработка приложений для распознавания лиц для Android (Java)
---
## Хронология
В списке перечислены только публичные проекты.

43
eng/index.html Normal file

File diff suppressed because one or more lines are too long

43
eng/works.html Normal file

File diff suppressed because one or more lines are too long

61
flake.lock generated
View file

@ -1,61 +0,0 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1741513245,
"narHash": "sha256-7rTAMNTY1xoBwz0h7ZMtEcd8LELk9R5TzBPoHuhNSCk=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "e3e32b642a31e6714ec1b712de8c91a3352ce7e1",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,30 +0,0 @@
{
description = "Pleshevski personal site";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
let
out = system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
pre-commit
nodejs_22
gnumake
pnpm
nodePackages.typescript-language-server # typescript
nodePackages.vscode-langservers-extracted # html, css, json, eslint
];
};
};
in
flake-utils.lib.eachDefaultSystem out;
}

43
index.html Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,35 +0,0 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "pleshevskiy",
"description": "Dmitriy Pleshevskiy",
"version": "1.0.2",
"type": "module",
"private": true,
"packageManager": "pnpm@10.7.1",
"scripts": {
"build": "vuepress build docs",
"dev": "vuepress dev docs"
},
"devDependencies": {
"@rushstack/eslint-patch": "1.11.0",
"@types/node": "22.14.0",
"@vitejs/plugin-vue": "5.2.3",
"@vue/eslint-config-prettier": "10.2.0",
"@vue/eslint-config-typescript": "14.5.0",
"@vue/language-server": "2.2.8",
"@vue/tsconfig": "0.7.0",
"@vue/typescript-plugin": "2.2.8",
"@vuepress/bundler-vite": "2.0.0-rc.7",
"@vuepress/plugin-blog": "2.0.0-rc.91",
"@vuepress/plugin-redirect": "2.0.0-rc.8",
"@vuepress/theme-default": "2.0.0-rc.91",
"eslint": "9.24.0",
"eslint-plugin-vue": "10.0.0",
"prettier": "3.5.3",
"sass": "1.86.3",
"typescript": "5.8.3",
"vue": "3.5.13",
"vue-tsc": "2.2.8",
"vuepress": "2.0.0-rc.20"
}
}

4803
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"configMigration": true,
"extends": ["config:recommended"],
"postUpdateOptions": ["pnpmDedupe"]
}

5
robots.txt Normal file
View file

@ -0,0 +1,5 @@
User-agent:*
Disallow:
Sitemap: https://pleshevski.ru/sitemap.xml

17
rus/index.html Normal file
View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex">
<meta http-equiv="refresh" content="0; url=/index.html">
<link rel="canonical" href="/index.html">
<title>Redirecting...</title>
<script>
const anchor = window.location.hash.substring(1);
location.href = `/index.html${anchor? `#${anchor}`: ""}`;
</script>
</head>
<body>
<p>Redirecting...</p>
</body>
</html>

17
rus/works.html Normal file
View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex">
<meta http-equiv="refresh" content="0; url=/works.html">
<link rel="canonical" href="/works.html">
<title>Redirecting...</title>
<script>
const anchor = window.location.hash.substring(1);
location.href = `/works.html${anchor? `#${anchor}`: ""}`;
</script>
</head>
<body>
<p>Redirecting...</p>
</body>
</html>

View file

@ -1,13 +0,0 @@
#! /usr/bin/env bash
# Can be used as a pre-commit hook
# Just symlink this file to .git/hooks/pre-commit
set -xe
if [ ! -z "$(git diff --cached --name-only | grep "^docs/")" ]
then
make build
git add dist
fi

3
sitemap.xml Normal file
View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://pleshevski.ru/</loc><lastmod>2025-03-12T12:50:22.000Z</lastmod><changefreq>monthly</changefreq><xhtml:link rel="alternate" hreflang="ru-RU" href="https://pleshevski.ru/"/><xhtml:link rel="alternate" hreflang="en-US" href="https://pleshevski.ru/eng/"/></url><url><loc>https://pleshevski.ru/works.html</loc><lastmod>2024-10-15T14:10:49.000Z</lastmod><changefreq>monthly</changefreq><xhtml:link rel="alternate" hreflang="ru-RU" href="https://pleshevski.ru/works.html"/><xhtml:link rel="alternate" hreflang="en-US" href="https://pleshevski.ru/eng/works.html"/></url><url><loc>https://pleshevski.ru/eng/</loc><lastmod>2025-03-12T12:50:22.000Z</lastmod><changefreq>monthly</changefreq><xhtml:link rel="alternate" hreflang="ru-RU" href="https://pleshevski.ru/"/><xhtml:link rel="alternate" hreflang="en-US" href="https://pleshevski.ru/eng/"/></url><url><loc>https://pleshevski.ru/eng/works.html</loc><lastmod>2024-08-07T08:48:54.000Z</lastmod><changefreq>monthly</changefreq><xhtml:link rel="alternate" hreflang="ru-RU" href="https://pleshevski.ru/works.html"/><xhtml:link rel="alternate" hreflang="en-US" href="https://pleshevski.ru/eng/works.html"/></url></urlset>

203
sitemap.xsl Normal file
View file

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Sitemap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0;" />
<style>
:root {
--bg-color: #f8f8f8;
--bg-color-secondary: #fff;
--text-color: #2c3e50;
--border-color: #eaecef;
--brand-color: #3eaf7c;
color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #0d1117;
--bg-color-secondary: #161b22;
--text-color: #ccc;
--border-color: #30363d;
}
}
html,
body {
margin: 0;
padding: 0;
background: var(--bg-color);
}
body {
min-height: 100vh;
color: var(--text-color);
text-align: center;
}
#content {
max-width: 960px;
margin: 0 auto;
}
h1 {
margin-top: 1rem;
font-size: 2rem;
}
@media (max-width: 419px) {
h1 {
font-size: 1.5rem;
}
}
a {
color: var(--text-color);
font-weight: 500;
overflow-wrap: break-word;
}
table {
width: 100%;
border-radius: 0.5rem;
border-collapse: collapse;
text-align: center;
overflow: hidden;
}
@media (max-width: 419px) {
table {
border-radius: 0;
}
}
th {
min-width: 3.5em;
padding: 0.6em 1em;
background-color: var(--brand-color);
color: var(--bg-color);
font-weight: bold;
font-size: 1rem;
}
@media (max-width: 719px) {
th {
font-size: 0.875rem;
}
}
th:first-child {
text-align: start;
}
tr:nth-child(odd) {
background: var(--bg-color-secondary);
}
tr:hover {
background-color: #e8e8e8;
}
@media (prefers-color-scheme: dark) {
tr:hover {
background-color: #333;
}
}
td {
padding: 0.6em 1em;
}
@media (max-width: 719px) {
td {
font-size: 0.75rem;
}
}
td:first-child {
text-align: start;
}
footer {
margin-top: 0.75rem;
padding: 0.25rem;
color: #888;
font-size: 0.75rem;
text-align: center;
}
</style>
</head>
<body>
<div id="content">
<h1>Sitemap</h1>
<table>
<thead>
<tr>
<th>
<xsl:value-of select="concat('URL (', count(sitemap:urlset/sitemap:url), ')')" />
</th>
<th>Priority</th>
<th>Change Frequency</th>
<th>Last Updated Time</th>
</tr>
</thead>
<tbody>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td>
<xsl:variable name="itemURL">
<xsl:value-of select="sitemap:loc" />
</xsl:variable>
<a href="{$itemURL}" target="_blank">
<xsl:value-of select="sitemap:loc" />
</a>
</td>
<td>
<xsl:choose>
<xsl:when test="sitemap:priority">
<xsl:value-of select="concat(sitemap:priority*100,'%a')" />
</xsl:when>
<xsl:otherwise>
<xsl:text>0.5</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:choose>
<xsl:when test="sitemap:changefreq">
<xsl:value-of select="concat(translate(substring(sitemap:changefreq, 1, 1),concat($lower, $upper),concat($upper, $lower)),substring(sitemap:changefreq, 2))" />
</xsl:when>
<xsl:otherwise>
<xsl:text>-</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
<footer>
Generatd by <a href="https://ecosystem.vuejs.press/plugins/sitemap/">@vuepress/plugin-sitemap</a>
</footer>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

View file

@ -1,11 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"composite": true,
"paths": {
"@/*": ["./docs/*"]
}
},
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "docs/**/*", "docs/**/*.vue"]
}

43
works.html Normal file

File diff suppressed because one or more lines are too long